基於shiro RBAC的表設計

weixin_33935777發表於2019-01-31

許可權控制的核心是RBAC,但是同個使用者可能具有多個角色,一個角色也可能關聯多個使用者。而這多與多的關聯關係維護起來特別麻煩,依照指定的角色具有的功能是相似的,所以在角色與使用者之間,新增了使用者組來進行中介進行管控。

GitHub https://github.com/oldguys/ShiroDemo

14387783-bcff3976a0e3a62f.jpg
rbac.jpg

實現Shiro自定義Realm

public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserEntityMapper userEntityMapper;
    @Autowired
    private RoleService roleService;

    /**
     *  授權
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        String userId = (String) principals.getPrimaryPrincipal();
        UserRoleFlag userRoleFlag = roleService.getUserRoleFlags(userId);

        return new SimpleAuthorizationInfo(userRoleFlag.getRoleFlags());
    }

    /**
     *  登入認證
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        String principal = (String) token.getPrincipal();
        System.out.println("登入校驗:" + principal);

        UserEntity entity = userEntityMapper.findByUsername(principal);

        if (null == entity) {
            throw new UnknownAccountException("未找到該使用者!");
        }

        System.out.println("獲取到使用者進行校驗....");
        return new SimpleAuthenticationInfo(principal, entity.getPassword(), getName());
    }
}

獲取角色許可權SQL

        SELECT
        d.*
        FROM
            sys_user_user_group a
        INNER JOIN sys_user_group b ON a.user_group_id = b.id
        INNER JOIN sys_role_user_group c ON a.user_group_id = c.user_group_id
        INNER JOIN sys_role d ON c.role_id = d.id
        WHERE
            b.`status` = 1
        AND d.`status` = 1
        AND a.user_id = #{userId}
進行許可權驗證

com.example.hrh.module.sys.controllers.TestController
必須指定角色許可權認證

    @RequiresRoles("admin")
    @RequestMapping("perm/admin")
    public String testAdmin() {
        System.out.println(SecurityUtils.getSubject().getPrincipal());
        return "admin許可權";
    }

相關文章