shiro權限認證與授權


什么是shiro

Shiroapache旗下一個開源框架,它將軟件系統的安全認證相關的功能抽取出來,實現用戶身份認證,權限授權、加密、會話管理等功能,組成了一個通用的安全認證框架。

 

為什么要用shiro

既然可以基於url實現權限的管理,為什么還要用shiro呢??

1.shiro將安全認證相關的功能抽取出來組成一個框架,使用shiro就可以非常快速的完成認證、授權等功能的開發,降低系統成本。最主要的就是方便了我們的開發。

2.shiro使用廣泛,shiro可以運行在web應用,非web應用,集群分布式應用中越來越多的用戶開始使用shiro

 

shiro認證

認證流程:

 

實例:

1.創建一個Java工程,並加入shiro-corejar包以及它的依賴包。

 

2.自定義realm

Shiro有自帶的IniRealmIniRealmini配置文件中讀取用戶的信息,大部分情況下需要從系統的數據庫中讀取用戶信息,所以需要自定義realm

 

[java]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. public class CustomRealm extends AuthorizingRealm {  
  2.   
  3.     @Override  
  4.     public String getName() {  
  5.         return "customRealm";  
  6.     }  
  7.   
  8.     // 用於認證  
  9.     @Override  
  10.     protected AuthenticationInfo doGetAuthenticationInfo(  
  11.             AuthenticationToken token) throws AuthenticationException {  
  12.   
  13.         // token是用戶輸入的  
  14.         // 第一步從token中取出身份信息  
  15.         String userCode = (String) token.getPrincipal();  
  16.   
  17.         // 第二步:根據用戶輸入的userCode從數據庫中查詢  
  18.         // 模擬從數據庫查詢到密碼  
  19.         String password = "111111";  
  20.   
  21.         // 如果查詢到返回認證信息AuthenticationInfo  
  22.   
  23.         SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(  
  24.                 userCode, password, this.getName());  
  25.         return simpleAuthenticationInfo;  
  26.     }  
  27. }  

 

3.配置shiro-realm.ini文件

[html]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. [main]  
  2. #自定義realm  
  3. customRealm=cn.itcast.shiro.realm.CustomRealm  
  4. #將realm設置到securityManager,相當於spring中注入  
  5. securityManager.realms=$customRealm  

4.創建認證代碼

[java]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1.  // 用戶登錄和退出  
  2. @Test  
  3. public void testCustomRealm() {  
  4.   
  5.     // 創建securityManager工廠,通過ini配置文件創建securityManager工廠  
  6.     Factory<SecurityManager> factory = new IniSecurityManagerFactory(  
  7.                 "classpath:shiro-realm.ini");  
  8.   
  9.     // 通過工廠創建SecurityManager  
  10.     SecurityManager securityManager = factory.getInstance();  
  11.   
  12.     // 將securityManager設置到運行環境中  
  13.     SecurityUtils.setSecurityManager(securityManager);  
  14.   
  15.     // 創建一個Subject實例,該實例認證要使用上邊創建的securityManager進行  
  16.     Subject subject = SecurityUtils.getSubject();  
  17.   
  18.     // 創建token令牌,記錄用戶認證的身份和憑證即賬號和密碼  
  19.     UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",  
  20.                 "111111");  
  21.   
  22.     try {  
  23.         // 用戶登陸  
  24.         subject.login(token);  
  25.     } catch (AuthenticationException e) {  
  26.         // TODO Auto-generated catch block  
  27.         e.printStackTrace();  
  28.     }  
  29.   
  30.     // 用戶認證狀態  
  31.   
  32.     Boolean isAuthenticated = subject.isAuthenticated();  
  33.   
  34.     System.out.println("用戶認證狀態:" + isAuthenticated);  
  35.   
  36.     // 用戶退出  
  37.   
  38.     subject.logout();  
  39.   
  40.     isAuthenticated = subject.isAuthenticated();  
  41.   
  42.     System.out.println("用戶認證狀態:" + isAuthenticated);  
  43.   
  44. }  

5.認證流程

1)創建token令牌,token中有用戶提交的認證信息即賬號和密碼

2)執行subject.login(token),最終由securityManager通過Authenticator進行認證

3Authenticator的實現ModularRealmAuthenticator調用realm從數據庫中取用戶真實的賬號和密碼

4CustomRealm先根據token中的賬號去數據庫中找該賬號,如果找不到則給ModularRealmAuthenticator返回null,如果找到則匹配密碼,匹配密碼成功則認證通過。

6.測試

登錄時用戶認證成功,退出時用戶認證失敗。

 

shiro授權

授權流程


 

授權方式

shiro支持三種方式的授權:

1.編程式

[java]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. Subject subject = SecurityUtils.getSubject();  
  2. if(subject.hasPermission(“admin”)) {  
  3. //有權限  
  4. else {  
  5. //無權限  
  6. }  

2.注解式

[java]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. @RequiresPermissions("admin")  
  2. public void hello() {  
  3. //有權限  
  4. }  

3.JSP/GSP標簽

[java]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. <shiro:hasPermission name="admin">  
  2. <!— 有權限—>  
  3. </shiro:hasRole>  

web系統集成中使用后兩種方式,我在這兒舉個簡單的例子就用第一種方式了。

實例

1.自定義realm

[java]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1.    // 用於授權  
  2. @Override  
  3. protected AuthorizationInfo doGetAuthorizationInfo(  
  4.         PrincipalCollection principals) {  
  5.     // 獲取身份信息  
  6.     //將getPrimaryPrincipal方法返回值轉為真實身份類型(在上邊的doGetAuthenticationInfo認證通過填充到Simpl)  
  7.     String username = (String) principals.getPrimaryPrincipal();  
  8.       
  9.     // 根據身份信息從數據庫中查詢權限數據  
  10.     // ....這里使用靜態數據模擬  
  11.     List<String> permissions = new ArrayList<String>();  
  12.     permissions.add("user:create");  
  13.     permissions.add("user:delete");  
  14.   
  15.     // 將權限信息封閉為AuthorizationInfo  
  16.     SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();  
  17.     for (String permission : permissions) {  
  18.         simpleAuthorizationInfo.addStringPermission(permission);  
  19.     }  
  20.   
  21.     return simpleAuthorizationInfo;  
  22.   
  23. }  

2.配置shiro-realm.ini文件與上面認證配置文件相同

3.創建授權代碼

[java]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. // 自定義realm進行資源授權測試  
  2. @Test  
  3. public void testAuthorizationCustomRealm() {  
  4.   
  5.     // 從ini文件中創建SecurityManager工廠  
  6.     Factory<SecurityManager> factory = new IniSecurityManagerFactory(  
  7.             "classpath:shiro-realm.ini");  
  8.   
  9.     // 創建SecurityManager  
  10.     SecurityManager securityManager = factory.getInstance();  
  11.   
  12.     // 將securityManager設置到運行環境  
  13.     SecurityUtils.setSecurityManager(securityManager);  
  14.   
  15.     // 創建主體對象  
  16.     Subject subject = SecurityUtils.getSubject();  
  17.   
  18.     // 對主體對象進行認證  
  19.     // 用戶登陸  
  20.     // 設置用戶認證的身份(principals)和憑證(credentials)  
  21.     UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",  
  22.             "111111");  
  23.     try {  
  24.         subject.login(token);  
  25.     } catch (AuthenticationException e) {  
  26.         // TODO Auto-generated catch block  
  27.         e.printStackTrace();  
  28.     }  
  29.   
  30.     // 用戶認證狀態  
  31.     Boolean isAuthenticated = subject.isAuthenticated();  
  32.   
  33.     System.out.println("用戶認證狀態:" + isAuthenticated);  
  34.   
  35.     // 授權檢測,失敗則拋出異常  
  36.     // subject.checkRole("role22");  
  37.   
  38.     // 基於資源授權  
  39.     System.out.println("是否擁有某一個權限:" + subject.isPermitted("user:delete"));  
  40.     System.out.println("是否擁有多個權限:"  
  41.             + subject.isPermittedAll("user:update", "user:delete"));  
  42.   
  43.     // 檢查權限  
  44.     subject.checkPermission("user:delete");  
  45.   
  46. }  

4.授權流程

1)執行subject.isPermitted("user:delete")

2securityManager通過ModularRealmAuthorizer進行授權

3ModularRealmAuthorizer調用realm獲取權限信息

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

5.測試


表明該用戶擁有delete權限但是不擁有update權限。

 

轉載:http://blog.csdn.net/u010539352/article/details/51220276


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM