1. 程式人生 > 實用技巧 >shiro原始碼分析-授權過程

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裡面。

  @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