天天看點

004-shiro授權授權三要素授權方法基于注釋的授權ModularRealmAuthorizerPermissionResolver和RolePermissionResolver

目錄

授權三要素

授權方法

授權順序

ModularRealmAuthorizer

PermissionResolver和RolePermissionResolver

WildcardPermission的規則簡單介紹如下:

授權三要素

授權具有三個在Shiro中引用的核心元素:權限,角色和使用者

權限:比如公司給你提供辦公電腦,你可以使用該電腦,你的同僚不能使用,但你不能将此電腦賣了換錢。(權限就是對某個資源的處理權。處理權分多種,這裡就是使用和變賣)

角色:在公司來說,員工就是角色,上司也是角色,他不是具體的某個人,可以隻某個崗位(研發、測試、産品),或者是某個部門(組織部、研發部),角色就是代表一類使用者,在授權中,角色就是代表擁有某些共同權限的一類使用者。

使用者:使用者是使用系統的使用者,一般情況下,使用者與角色綁定,角色與權限綁定,那麼該使用者擁有哪些權限自然就知道了。

三者的簡單關系:一個使用者可以擁有多個角色,一個角色擁有多個權限。有些系統可能角色和權限一起使用或者沒有角色,直接将權限賦予使用者。

授權方法

我們使用subject類的如下方法來進行權限認證:

  • boolean isPermitted(String var1);
    • 是否有某個權限
  • boolean isPermitted(Permission var1);
  • boolean[] isPermitted(String... var1);
    • 傳回是否有對應權限的數組
  • boolean[] isPermitted(List<Permission> var1);
    • 同上
  • boolean isPermittedAll(String... var1);
    • 是否擁有清單中的所有權限
  • boolean isPermittedAll(Collection<Permission> var1);
    • 同上
  • void checkPermission(String var1) throws AuthorizationException;
    • 是否擁有權限(如果沒有将抛出AuthorizationException異常)下同,依此類推
  • void checkPermission(Permission var1) throws AuthorizationException;
  • void checkPermissions(String... var1) throws AuthorizationException;
  • void checkPermissions(Collection<Permission> var1) throws AuthorizationException;
  • boolean hasRole(String var1);
  • boolean[] hasRoles(List<String> var1);
  • boolean hasAllRoles(Collection<String> var1);
  • void checkRole(String var1) throws AuthorizationException;
  • void checkRoles(Collection<String> var1) throws AuthorizationException;
  • void checkRoles(String... var1) throws AuthorizationException;

總結:has*方法,驗證失敗将傳回false,而check*方法,驗證失敗将抛出AuthorizationException異常。實際使用中根據情況選用,大部分是使用check*方法讓他抛出異常。

基于注釋的授權

基于注解的授權需要你的程式是支援AOP的,我們常見的是在Spring的AOP架構下使用

RequiresAuthentication

注解

調用被該注解修飾的方法時,subject是已認證的,其等效于SecurityUtils.getSubject().isAuthenticated() == true

@RequiresAuthentication
public void updateAccount(Account userAccount) {
    //需要是已認證的Subject才能調用該方法
    ...
}
           

RequiresGuest

注解

允許遊客通路

@RequiresGuest
public void signUp(User newUser) {
    //允許遊客通路
    ...
}
           

其等效于如下代碼:

Subject currentUser = SecurityUtils.getSubject();
PrincipalCollection principals = currentUser.getPrincipals();
if (principals != null && !principals.isEmpty()) {
      throw new AuthorizationException(...);
}
           

RequiresPermissions

注解

允許某個或某些權限通路

RequiresRoles注解

允許某個或某些角色通路

RequiresUser

注解

允許已知身份的使用者通路(

Subject

具有已知身份的,該身份是由于在目前會話期間進行了身份驗證而已知的,或者是從先前會話的“ RememberMe”服務中記住的)

關于注解的使用示例,我們将在後面的shiro的web內建中展示。此處了解即可。

授權順序

004-shiro授權授權三要素授權方法基于注釋的授權ModularRealmAuthorizerPermissionResolver和RolePermissionResolver
  • 步驟1:應用程式或架構Subject所有如下方法( hasRole*,checkRole*,isPermitted*,或checkPermission*方法變體)進行權限或角色的授權驗證。
  • 步驟2:一般情況下,程式中的Subject是DelegatingSubject(或其子類)調用上面的方法時,實際上是使用的SecurityManager的hasRole*,checkRole*,isPermitted*,或checkPermission*方法變體(securityManager而實作了org.apache.shiro.authz.Authorizer接口,hasRole*,checkRole*,isPermitted*,或checkPermission*方法變體這些方法是Authorizer接口的定義)。
  • 步驟3:在我們使用SecurityManager時。Authorizer接口預設實作是ModularRealmAuthorizer,該執行個體是一個執行個體,它支援Realm在任何授權操作期間協調一個或多個執行個體。
  • 步驟4:Realm檢查每個已配置的配置,以檢視是否實作了相同的Authorizer接口。如果是這樣,ModularRealmAuthorizer調用該領域的各自的hasRole*,checkRole*,isPermitted*,或checkPermission*方法被調用。

總結:從上我們可以了解到,所有的認證權限的方法,最終都是調用的Realm中對應的hasRole*,checkRole*,isPermitted*,或checkPermission*方法

ModularRealmAuthorizer

上面我們提到,ModularRealmAuthorizer是Authorizer接口的預設實作,而且我們的SecurityManager也預設使用它,它來協調執行每個配置好的Realm。它的執行規則如下:

  • 如果Realm自身實作Authorizer接口,其各自的Authorizer對應的方法(hasRole*,checkRole*,isPermitted*,或checkPermission*)被調用。
    • 如果Realm的方法導緻異常,則将抛出AuthorizationException異常給Subject調用方。這會縮短授權過程,并且該授權操作将不再執行任何剩餘的領域。
    • 如果Realm的方法是傳回布爾值的hasRole*或isPermitted*變體,并且傳回值是true,則該true值将立即傳回,并且所有剩餘的Realms都将不再執行。
  • 如果Realm不實作該Authorizer接口,則将其忽略。

PermissionResolver和RolePermissionResolver

Resolver顧名思義,就是權限和角色的解析器(預設情況下,我們的權限或角色我們都直接通過字元串的形式進行表示,如果你需要自定義其他方式,或其他的解析方式,就需要使用這兩個接口來實作--建議是使用預設方式就夠了)

這兩個接口都會将我們提供的角色或權限的字元串解析為Permission對象,Permission對象的預設實作是WildcardPermission,WildcardPermission定義了權限字元串的解析方式和定義規則。

一般情況下,我們的Realm會實作PermissionResolverAware和RolePermissionResolverAware兩個接口,這兩個接口提供了PermissionResolver和RolePermissionResolver的設定,如果我們自定義Resolver的話,就需要使用realm的對應的set方法進行設定。

WildcardPermission的規則簡單介紹如下:

單個權限表示:query

多級的權限表示:

  • test:query:我們可以用test來表示菜單,query表示操作,該權限表示擁有test菜的的query操作權限
  • a:test:query:更多級的權限表示

"*"的使用:

  • test:*:表示我們可以使用test菜單下的所有操作(該權限表示包含了test:query權限)

上一篇:003-認證

下一篇:005-shiro的Realm源碼解析與自定義Realm

繼續閱讀