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; }
9.返回到AuthorizingRealm中的hasRole()方法。
10.在hasRole()方法里面,只是通过判断集合中是否有该角色。返回布尔值。
posted on 2020-07-15 18:13 ajax取个名字真难 阅读(163) 评论(0) 编辑 收藏 举报