shiro控制权限认证的原理

现在在前端加上shiro的标签: shiro:hasPermission=“aaa”,访问该页面时,检测到shiro的标签,那么就会进入后端shiro的权限校验:

DelegatingSubject 实现 Subject接口,里面有个isPermitted(String permission)方法,其中permission参数就是前端获取到的aaa

 public boolean isPermitted(String permission) {
        return this.hasPrincipals() && this.securityManager.isPermitted(this.getPrincipals(), permission);
 }


//验证Principals是否为空
protected boolean hasPrincipals() {
        return !isEmpty(this.getPrincipals());
}
public PrincipalCollection getPrincipals() {
     List<PrincipalCollection> runAsPrincipals = this.getRunAsPrincipalsStack();
     return CollectionUtils.isEmpty(runAsPrincipals) ? this.principals : (PrincipalCollection)runAsPrincipals.get(0);
}

然后进入securityManager.isPermitted(this.getPrincipals(), permission)方法,实际进入AuthorizingSecurityManager类,该类是securityManager接口的实现类:

 public boolean isPermitted(PrincipalCollection principals, String permissionString) {
        return this.authorizer.isPermitted(principals, permissionString);
 }

调用authorizer.isPermitted(principals, permissionString),进入authorizer的实现类ModularRealmAuthorizer:

public boolean isPermitted(PrincipalCollection principals, String permission) {
        this.assertRealmsConfigured();
        Iterator var3 = this.getRealms().iterator();

        Realm realm;
        do {
            if (!var3.hasNext()) {
                return false;
            }

            realm = (Realm)var3.next();
        } while(!(realm instanceof Authorizer) || !((Authorizer)realm).isPermitted(principals, permission));

        return true;
    }

获取到一个realm的对象,该对象是Authorizer的一个实例,调用((Authorizer)realm).isPermitted(principals, permission))方法,实际是进入AuthorizingRealm类:

public boolean isPermitted(PrincipalCollection principals, String permission) {
        Permission p = this.getPermissionResolver().resolvePermission(permission);
        return this.isPermitted(principals, p);
 }

public boolean isPermitted(PrincipalCollection principals, Permission permission) {
        AuthorizationInfo info = this.getAuthorizationInfo(principals);  //根据登录的用户信息获取权限
        return this.isPermitted(permission, info);
 }

//获取到用户的权限信息,该方法将权限信息和传入的permission进行比较,
protected boolean isPermitted(Permission permission, AuthorizationInfo info) {
        Collection<Permission> perms = this.getPermissions(info);
        if (perms != null && !perms.isEmpty()) {
            Iterator var4 = perms.iterator();

            while(var4.hasNext()) {
                Permission perm = (Permission)var4.next();
                if (perm.implies(permission)) {
                    return true;
                }
          }
          
}

上段代码中的this.getAuthorizationInfo(principals)方法进入自己编写的类MyShiroRealm extends AuthorizingRealm,这里就是实现获取权限信息的过程:

 @Override
    //登录进入有principals的缓存cn.com.soyea.common.core.entity.vo.UserVO@42ff0600
    public AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {
        if (null == principals) {
            return null;
        } else {
            //根据用户名从缓存中读取权限信息
            AuthorizationInfo authorizationInfo = super.getAuthorizationCache().get(((User) principals.getPrimaryPrincipal()).getUserName());
            if (null == authorizationInfo) {
                //重新获取权限信息
                authorizationInfo = this.doGetAuthorizationInfo(principals);
                return authorizationInfo;
            } else {
                //获取缓存中权限的perms和roles
                Set<String> perms = (Set<String>) authorizationInfo.getStringPermissions();
                Set<String> roles = (Set<String>) authorizationInfo.getRoles();
                if (perms == null || perms.size() == 0 || roles == null || roles.size() == 0) {
                    //perms或roles为null,重新获取权限信息
                    authorizationInfo = this.doGetAuthorizationInfo(principals);
                    return authorizationInfo;
                } else {
                    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
                    info.addStringPermissions(perms);
                    info.addRoles(roles);
                    return info;
                }
            }
        }
    }

 /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        Object principal = principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        if (principal instanceof UserVO) {
            UserVO userVO = (UserVO) principal;
            List<Role> roleList = userVO.getRoleList();
            if (null != roleList && roleList.size() > 0) {
                Set<String> roles = new HashSet<>();
                Set<String> permissions = new HashSet<>();
                for (Role role : roleList) {
                    roles.add(role.getRoleName());
                    R r =xxx.getResourcesByRoleId(role.getId());
                    if (null == r || !r.get("code").toString().equals("200") || !r.containsKey("data") || null == r.get("data")) {
                        return null;
                    }
                    List<Resource> resourceList = R.getListData(r, Resource.class);
                    if (null != resourceList && 0 < resourceList.size()) {
                        for (int i = 0; i < resourceList.size(); i++) {
                            permissions.add(resourceList.get(i).getResourcePerm());
                        }
                    }
                }

                authorizationInfo.addStringPermissions(permissions);
                authorizationInfo.addRoles(roles);

                //获取缓存对象,并向对象中注入新的用户名和info
                super.getAuthorizationCache().put(userVO.getUserName(), authorizationInfo);
            }
        }
        return authorizationInfo;
    }

猜你喜欢

转载自blog.csdn.net/xiao_Ray/article/details/90903582