shiro教程(3)-shiro授權

shiro授權

 

1.1 授權流程

 

1.2 授權方式

Shiro 支持三種方式的授權:

1、編程式:通過寫if/else 授權代碼塊完成:

Subject subject = SecurityUtils.getSubject();

if(subject.hasRole(“admin”)) {

//有權限

} else {

//無權限

}

2、註解式:通過在執行的Java方法上放置相應的註解完成:

@RequiresRoles("admin")

public void hello() {

//有權限

}

3、 JSP/GSP 標籤:在JSP/GSP頁面通過相應的標籤完成:

<shiro:hasRole name="admin">

<!— 有權限—>

</shiro:hasRole>

 

本教程序授權測試使用第一種編程方式,實際與web系統集成使用後兩種方式。

 

1.3 授權測試

1.3.1 shiro-permission.ini

創建存放權限的配置文件shiro-permission.ini,如下:

[html] view plain copy print?在CODE上查看代碼片派生到我的代碼片

  1. [users]  

  2. #用戶zhang的密碼是123,此用戶具有role1和role2兩個角色  

  3. zhang=123,role1,role2  

  4. wang=123,role2  

  5.   

  6. [roles]  

  7. #角色role1對資源user擁有create、update權限  

  8. role1=user:create,user:update  

  9. #角色role2對資源user擁有create、delete權限  

  10. role2=user:create,user:delete  

  11. #角色role3對資源user擁有create權限  

  12. role3=user:create  



 

ini文件中用戶、角色、權限的配置規則是:“用戶名=密碼,角色1,角色2...” “角色=權限1,權限2...”,首先根據用戶名找角色,再根據角色找權限,角色是權限集合。

 

 

 

1.3.2 權限字符串規則

權限字符串的規則是:“資源標識符:操作:資源實例標識符”,意思是對哪個資源的哪個實例具有什麼操作,“:”是資源/操作/實例的分割符,權限字符串也可以使用*通配符。

 

例子:

用戶創建權限:user:create,或user:create:*

用戶修改實001的權限:user:update:001

用戶實例001的所有權限:user*001

 

 

1.3.3 測試代碼

 

測試代碼同認證代碼,注意ini地址改爲shiro-permission.ini,主要學習下邊授權的方法,注意:在用戶認證通過後執行下邊的授權代碼。

 

[java] view plain copy print?在CODE上查看代碼片派生到我的代碼片

  1. @Test  

  2.   

  3. public void testPermission() {  

  4.   

  5.    

  6.   

  7. // 從ini文件中創建SecurityManager工廠  

  8.   

  9. Factory<SecurityManager> factory = new IniSecurityManagerFactory(  

  10.   

  11. "classpath:shiro-permission.ini");  

  12.   

  13.    

  14.   

  15. // 創建SecurityManager  

  16.   

  17. SecurityManager securityManager = factory.getInstance();  

  18.   

  19.    

  20.   

  21. // 將securityManager設置到運行環境  

  22.   

  23. SecurityUtils.setSecurityManager(securityManager);  

  24.   

  25.    

  26.   

  27. // 創建主體對象  

  28.   

  29. Subject subject = SecurityUtils.getSubject();  

  30.   

  31.    

  32.   

  33. // 對主體對象進行認證  

  34.   

  35. // 用戶登陸  

  36.   

  37. // 設置用戶認證的身份(principals)和憑證(credentials)  

  38.   

  39. UsernamePasswordToken token = new UsernamePasswordToken("zhang""123");  

  40.   

  41. try {  

  42.   

  43. subject.login(token);  

  44.   

  45. catch (AuthenticationException e) {  

  46.   

  47. // TODO Auto-generated catch block  

  48.   

  49. e.printStackTrace();  

  50.   

  51. }  

  52.   

  53.    

  54.   

  55. // 用戶認證狀態  

  56.   

  57. Boolean isAuthenticated = subject.isAuthenticated();  

  58.   

  59.    

  60.   

  61. System.out.println("用戶認證狀態:" + isAuthenticated);  

  62.   

  63.    

  64.   

  65. // 用戶授權檢測 基於角色授權  

  66.   

  67. // 是否有某一個角色  

  68.   

  69. System.out.println("用戶是否擁有一個角色:" + subject.hasRole("role1"));  

  70.   

  71. // 是否有多個角色  

  72.   

  73. System.out.println("用戶是否擁有多個角色:" + subject.hasAllRoles(Arrays.asList("role1""role2")));  

  74.   

  75. //subject.checkRole("role1");  

  76.   

  77. //subject.checkRoles(Arrays.asList("role1", "role2"));  

  78.   

  79.    

  80.   

  81. // 授權檢測,失敗則拋出異常  

  82.   

  83. // subject.checkRole("role22");  

  84.   

  85.    

  86.   

  87. // 基於資源授權  

  88.   

  89. System.out.println("是否擁有某一個權限:" + subject.isPermitted("user:delete"));  

  90.   

  91. System.out.println("是否擁有多個權限:" + subject.isPermittedAll("user:create:1","user:delete"));  

  92.   

  93. //檢查權限  

  94.   

  95. subject.checkPermission("sys:user:delete");  

  96.   

  97. subject.checkPermissions("user:create:1","user:delete");  

  98.   

  99.    

  100.   

  101. }  



 

 

1.3.4 基於角色的授權

[java] view plain copy print?在CODE上查看代碼片派生到我的代碼片

  1. // 用戶授權檢測 基於角色授權  

  2.   

  3. // 是否有某一個角色  

  4.   

  5. System.out.println("用戶是否擁有一個角色:" + subject.hasRole("role1"));  

  6.   

  7. // 是否有多個角色  

  8.   

  9. System.out.println("用戶是否擁有多個角色:" + subject.hasAllRoles(Arrays.asList("role1""role2")));  



 

對應的check方法:


subject.checkRole("role1");

subject.checkRoles(Arrays.asList("role1","role2"));

 

上邊check方法如果授權失敗則拋出異常:

[java] view plain copy print?在CODE上查看代碼片派生到我的代碼片

  1. org.apache.shiro.authz.UnauthorizedException: Subject does not have role [.....]  



 

 

1.3.5 基於資源授權

 

[java] view plain copy print?在CODE上查看代碼片派生到我的代碼片

  1. // 基於資源授權  

  2.   

  3. System.out.println("是否擁有某一個權限:" + subject.isPermitted("user:delete"));  

  4.   

  5. System.out.println("是否擁有多個權限:" + subject.isPermittedAll("user:create:1","user:delete"));  

  6.   

  7. 對應的check方法:  

  8.   

  9. subject.checkPermission("sys:user:delete");  

  10.   

  11. subject.checkPermissions("user:create:1","user:delete");  



 

 

上邊check方法如果授權失敗則拋出異常:

[java] view plain copy print?在CODE上查看代碼片派生到我的代碼片

  1. org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [....]  



 

 

1.4 自定義realm

與上邊認證自定義realm一樣,大部分情況是要從數據庫獲取權限數據,這裏直接實現基於資源的授權。

1.4.1 realm代碼

 

在認證章節寫的自定義realm類中完善doGetAuthorizationInfo方法,此方法需要完成:根據用戶身份信息從數據庫查詢權限字符串,由shiro進行授權。

 

[java] view plain copy print?在CODE上查看代碼片派生到我的代碼片

  1. // 授權  

  2.   

  3. @Override  

  4.   

  5. protected AuthorizationInfo doGetAuthorizationInfo(  

  6.   

  7. PrincipalCollection principals) {  

  8.   

  9. // 獲取身份信息  

  10.   

  11. String username = (String) principals.getPrimaryPrincipal();  

  12.   

  13. // 根據身份信息從數據庫中查詢權限數據  

  14.   

  15. //....這裏使用靜態數據模擬  

  16.   

  17. List<String> permissions = new ArrayList<String>();  

  18.   

  19. permissions.add("user:create");  

  20.   

  21. permissions.add("user.delete");  

  22.   

  23. //將權限信息封閉爲AuthorizationInfo  

  24.   

  25. SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();  

  26.   

  27. for(String permission:permissions){  

  28.   

  29. simpleAuthorizationInfo.addStringPermission(permission);  

  30.   

  31. }  

  32.   

  33. return simpleAuthorizationInfo;  

  34.   

  35. }  



 

 

1.4.2 shiro-realm.ini

ini配置文件還使用認證階段使用的,不用改變。


 

1.4.3 測試代碼

同上邊的授權測試代碼,注意修改ini地址爲shiro-realm.ini

 

 

1.4.4 授權執行流程

1、 執行subject.isPermitted("user:create")

2、 securityManager通過ModularRealmAuthorizer進行授權

3、 ModularRealmAuthorizer調用realm獲取權限信息

4、ModularRealmAuthorizer再通過permissionResolver解析權限字符串,校驗是否匹配


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章