shiro源码分析-授权过程

二。shiro的授权过程源码分析

1.shiro不管是基于url的粗粒度权限控制,还是基于方法的细粒度权限控制。每个请求,都会经过PathMatchingFilter类的preHandle方法来校验url。关于shiro的filter再将。

我们就从RolesAuthorizationFilter的isAccessAllowed()方法开始解读。因为该方法中调用了subject.hasAllRoles(roles)方法。事实上,所有的授权都是从subject的授权方法开始。

 2.跟进去。发现授权跟认证一样,都是调用SecurityManager来执行。hasPrincipals()方法会返回true。因为你登录后token中的Principal信息,就会存在。这里就不会为空。

 3.跟进去。进到AuthorizingSecurityManager的hasRole()方法。这里的this.authorizer就是shiro的授权器,它是个接口。默认实现是ModularRealmAuthorizer。

 4.进入到ModularRealmAuthorizer的hasAllRoles()。这里所有的角色都匹配的话,就返回true。反之则返回false。

 5.进入到进入到ModularRealmAuthorizer的hasRole()方法。这里的realm都是我们开发的realm。因为我们开发的realm继承AuthorizingRealm,AuthorizingRealm继承AuthenticatingRealm,而AuthenticatingRealm又实现了Authorizer接口。因此可以强转为Authorizer。

 6.跟踪进去。因为realm继承了AuthorizingRealm。因此此时代码跳到AuthorizingRealm的hasRole()方法。getAuthorizationInfo()方法,就是获取授权信息。AuthorizationInfo里面就是授权信息。

 7.继续进入到getAuthorizationInfo()方法。跟认证一样,首先从缓存中获取,缓存中获取不到,再调用realm去数据库获取。

 8.我们开发的realm里面重写了doGetAuthorizationInfo()方法。此时跳到我们写的realm里面。构造对象SimpleAuthorizationInfo,此对象包涵用户的角色和权限信息,然后一路返回。

  @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        UserVO user = (UserVO) principals.getPrimaryPrincipal();

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        Set<RoleVO> roles = roleService.listRoleByUserId(user.getUserId());

        List<Integer> roleIds = new ArrayList<>();
        for (RoleVO role : roles) {
            authorizationInfo.addRole(role.getRoleCode());
            roleIds.add(role.getRoleId());
        }


        if (!roleIds.isEmpty()) {
            Set<PermissionVO> permissions = permissionService.listPermissionByRoleIds(roleIds);

            Set<String> collect = permissions.parallelStream()
                    .map(PermissionVO::getPermissionCode)
                    .collect(Collectors.toSet());

            authorizationInfo.addStringPermissions(collect);
        }
        return authorizationInfo;
    }
View Code

 9.返回到AuthorizingRealm中的hasRole()方法。

 10.在hasRole()方法里面,只是通过判断集合中是否有该角色。返回布尔值。

原文地址:https://www.cnblogs.com/step-and-step/p/13307130.html