久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

將 Shiro 作為應(yīng)用的權(quán)限基礎(chǔ) 三:基于注解實現(xiàn)的授權(quán)認(rèn)證過程

 clarkbourne 2017-03-09

授權(quán)即訪問控制,,它將判斷用戶在應(yīng)用程序中對資源是否擁有相應(yīng)的訪問權(quán)限,。 

如,判斷一個用戶有查看頁面的權(quán)限,,編輯數(shù)據(jù)的權(quán)限,,擁有某一按鈕的權(quán)限等等。 

 

一,、用戶權(quán)限模型

為實現(xiàn)一個較為靈活的用戶權(quán)限數(shù)據(jù)模型,,通常把用戶信息單獨用一個實體表示,用戶權(quán)限信息用兩個實體表示,。

  1. 用戶信息用 LoginAccount 表示,,最簡單的用戶信息可能只包含用戶名 loginName 及密碼 password 兩個屬性。實際應(yīng)用中可能會包含用戶是否被禁用,,用戶信息是否過期等信息,。
  2. 用戶權(quán)限信息用 Role 與 Permission 表示,Role 與 Permission 之間構(gòu)成多對多關(guān)系,。Permission 可以理解為對一個資源的操作,,Role 可以簡單理解為 Permission 的集合。
  3. 用戶信息與 Role 之間構(gòu)成多對多關(guān)系,。表示同一個用戶可以擁有多個 Role,,一個 Role 可以被多個用戶所擁有,。

 


 

權(quán)限聲明及粒度 

Shiro權(quán)限聲明通常是使用以冒號分隔的表達(dá)式。就像前文所講,,一個權(quán)限表達(dá)式可以清晰的指定資源類型,,允許的操作,。同時,Shiro權(quán)限表達(dá)式支持簡單的通配符,,可以更加靈活的進行權(quán)限設(shè)置,。 

下面以實例來說明權(quán)限表達(dá)式。 

可查詢用戶數(shù)據(jù) 

User:view 

可查詢或編輯用戶數(shù)據(jù) 

User:view,edit 

可對用戶數(shù)據(jù)進行所有操作 

User:*或 user 

可編輯id為123的用戶數(shù)據(jù) 

User:edit:123 

 

授權(quán)處理過程

認(rèn)證通過后接受 Shiro 授權(quán)檢查,,授權(quán)驗證時,,需要判斷當(dāng)前角色是否擁有該權(quán)限。

只有授權(quán)通過,,才可以訪問受保護 URL 對應(yīng)的資源,,否則跳轉(zhuǎn)到“未經(jīng)授權(quán)頁面”。

如果我們自定義Realm實現(xiàn),,比如我后面的例子中,,自定義了ShiroDbRealm類,,當(dāng)訪問被@RequiresPermissions注解的方法時,會先執(zhí)行ShiroDbRealm.doGetAuthorizationInfo()進行授權(quán),。

  1. <span style="font-size:18px">@Controller  
  2. @RequestMapping(value = "/user")  
  3. public class UserController {  
  4.    
  5. @Resource(name="userService")  
  6. private IUserService userService;  
  7.    
  8. /** 
  9.  * 測試權(quán)限 
  10.  * 只有擁有 user:create權(quán)限,,才能進行注冊 
  11.  * @param user 
  12.  * @return 
  13.  */  
  14. @RequestMapping(value = "/register")  
  15. @ResponseBody  
  16. @RequiresPermissions("user:create")  
  17. public boolean register(User user){  
  18. return userService.register(user);  
  19. }</span>  


 

 

二、授權(quán)實現(xiàn) 

Shiro支持三種方式實現(xiàn)授權(quán)過程: 

  • 編碼實現(xiàn)
  • 注解實現(xiàn)
  • JSP Taglig實現(xiàn)

 

1,、基于編碼的授權(quán)實現(xiàn) 

1,、基于權(quán)限對象的實現(xiàn) 

創(chuàng)建org.apache.shiro.authz.Permission的實例,將該實例對象作為參數(shù)傳遞給Subject.isPermitted()進行驗證,。 

      

  1. Permission printPermission = new PrinterPermission("laserjet4400n", "print");    
  2. Subject currentUser = SecurityUtils.getSubject();    
  3. if (currentUser.isPermitted(printPermission)) {    
  4.     //show the Print button    
  5. } else {    
  6.     //don't show the button?  Grey it out?    
  7. }    

 

2,、基于字符串的實現(xiàn) 

相比笨重的基于對象的實現(xiàn)方式,基于字符串的實現(xiàn)便顯得更加簡潔,。 

       

  1. Subject currentUser = SecurityUtils.getSubject();    
  2. if (currentUser.isPermitted("printer:print:laserjet4400n")) {    
  3.     //show the Print button    
  4. } else {    
  5.     //don't show the button?  Grey it out?    
  6. }    

使用冒號分隔的權(quán)限表達(dá)式是org.apache.shiro.authz.permission.WildcardPermission默認(rèn)支持的實現(xiàn)方式,。 

這里分別代表了資源類型:操作:資源ID 

 

2、基于注解的授權(quán)實現(xiàn) 

Shiro注解支持AspectJ,、spring,、Google-Guice等,可根據(jù)應(yīng)用進行不同的配置,。 

 

相關(guān)的注解: 

@RequiresAuthentication 

可以用戶類/屬性/方法,,用于表明當(dāng)前用戶需是經(jīng)過認(rèn)證的用戶。  

        

  1. @RequiresAuthentication    
  2. public void updateAccount(Account userAccount) {    
  3.     //this method will only be invoked by a     
  4.     //Subject that is guaranteed authenticated    
  5.     ...    
  6. }   

@RequiresPermissions 

當(dāng)前用戶需擁有制定權(quán)限 

       

  1. @RequiresPermissions("account:create")    
  2. public void createAccount(Account account) {    
  3.     //this method will only be invoked by a Subject    
  4.     //that is permitted to create an account    
  5.     ...    
  6. }   

 

 

3,、基于JSP TAG的授權(quán)實現(xiàn) 

Shiro提供了一套JSP標(biāo)簽庫來實現(xiàn)頁面級的授權(quán)控制,。 

在使用Shiro標(biāo)簽庫前,首先需要在JSP引入shiro標(biāo)簽: 

  1. <%@ taglib prefix="shiro" uri="http://shiro./tags" %>  

hasRole標(biāo)簽 

驗證當(dāng)前用戶是否屬于該角色

  1. <shiro:hasRole name="administrator">    
  2.     <a href="admin.jsp">Administer the system</a>    
  3. </shiro:hasRole>    
 

hasPermission標(biāo)簽 

驗證當(dāng)前用戶是否擁有制定權(quán)限 

  1. <shiro:hasPermission name="user:create">    
  2.     <a href="createUser.jsp">Create a new User</a>    
  3. </shiro:hasPermission>    


 

三,、Shiro授權(quán)的內(nèi)部處理機制 


 

1,、在應(yīng)用程序中調(diào)用授權(quán)驗證方法(Subject的isPermitted*或hasRole*等) 

2、Sbuject會委托應(yīng)用程序設(shè)置的securityManager實例調(diào)用相應(yīng)的isPermitted*或hasRole*方法,。 

3,、接下來SecurityManager會委托內(nèi)置的Authorizer的實例(默認(rèn)是ModularRealmAuthorizer類的實例,類似認(rèn)證實例)調(diào)用相應(yīng)的授權(quán)方法,。 

4,、每一個Realm將檢查是否實現(xiàn)了相同的Authorizer 接口。然后,,將調(diào)用Reaml自己的相應(yīng)的授權(quán)驗證方法,。 

 

四、授權(quán)代碼

UserController:處理用戶登錄后的請求(注冊)

    

  1. package org.shiro.demo.controller;  
  2.   
  3. import javax.annotation.Resource;  
  4.   
  5. import org.apache.shiro.authz.annotation.RequiresPermissions;  
  6. import org.apache.shiro.authz.annotation.RequiresRoles;  
  7. import org.shiro.demo.entity.User;  
  8. import org.shiro.demo.service.IUserService;  
  9. import org.springframework.stereotype.Controller;  
  10. import org.springframework.web.bind.annotation.RequestMapping;  
  11. import org.springframework.web.bind.annotation.ResponseBody;  
  12.   
  13. @Controller  
  14. @RequestMapping(value = "/user")  
  15. public class UserController {  
  16.       
  17.     @Resource(name="userService")  
  18.     private IUserService userService;  
  19.   
  20.     /** 
  21.      * 測試權(quán)限 
  22.      * 只有擁有 user:create 權(quán)限,,才能進行注冊 
  23.      * @param user 
  24.      * @return 
  25.      */  
  26.     @RequestMapping(value = "/register")  
  27.     @ResponseBody  
  28.     @RequiresPermissions("user:create")  
  29.     public boolean register(User user){  
  30.         return userService.register(user);  
  31.     }  
  32.       
  33.     /** 
  34.      * 測試角色 
  35.      * 只有擁有 administrator 角色,,才能跳轉(zhuǎn)到register頁面 
  36.      * @return 
  37.      */  
  38.     @RequestMapping(value = "/toRegister")  
  39.     @RequiresRoles("administrator")  
  40.     public String toRegister(){  
  41.         return "/system/user/register";  
  42.     }  
  43. }  

 

ShiroDbRealm:自定義的指定Shiro驗證用戶授權(quán)的類

  1. <span style="font-size:18px">packageorg.shiro.demo.service.realm;  
  2.    
  3. importjava.util.ArrayList;  
  4. importjava.util.List;  
  5.    
  6. importjavax.annotation.Resource;  
  7.    
  8. importorg.apache.commons.lang.StringUtils;  
  9. importorg.apache.shiro.authc.AuthenticationException;  
  10. importorg.apache.shiro.authc.AuthenticationInfo;  
  11. importorg.apache.shiro.authc.AuthenticationToken;  
  12. importorg.apache.shiro.authc.SimpleAuthenticationInfo;  
  13. importorg.apache.shiro.authc.UsernamePasswordToken;  
  14. importorg.apache.shiro.authz.AuthorizationException;  
  15. importorg.apache.shiro.authz.AuthorizationInfo;  
  16. importorg.apache.shiro.authz.SimpleAuthorizationInfo;  
  17. importorg.apache.shiro.realm.AuthorizingRealm;  
  18. importorg.apache.shiro.subject.PrincipalCollection;  
  19. importorg.shiro.demo.entity.Permission;  
  20. importorg.shiro.demo.entity.Role;  
  21. importorg.shiro.demo.entity.User;  
  22. importorg.shiro.demo.service.IUserService;  
  23.    
  24. /** 
  25.  * 自定義的指定Shiro驗證用戶登錄的類 
  26.  * @author TCH 
  27.  * 
  28.  */  
  29. publicclass ShiroDbRealm extends AuthorizingRealm{  
  30.    
  31. //@Resource(name="userService")  
  32. privateIUserService userService;  
  33.    
  34. publicvoid setUserService(IUserService userService) {  
  35. this.userService= userService;  
  36. }  
  37.    
  38.     /** 
  39.      * 為當(dāng)前登錄的Subject授予角色和權(quán)限 
  40.      * @see 經(jīng)測試:本例中該方法的調(diào)用時機為需授權(quán)資源被訪問時 
  41.      * @see經(jīng)測試:并且每次訪問需授權(quán)資源時都會執(zhí)行該方法中的邏輯,這表明本例未啟用AuthorizationCache 
  42.      * @seeweb層可以有shiro的緩存,dao層可以配有hibernate的緩存(后面介紹) 
  43.      */  
  44. protectedAuthorizationInfo doGetAuthorizationInfo(  
  45. PrincipalCollectionprincipals) {  
  46.    
  47. //獲取當(dāng)前登錄的用戶名,等價于(String)principals.fromRealm(this.getName()).iterator().next()   
  48. Stringaccount = (String) super.getAvailablePrincipal(principals);  
  49.    
  50. List<String>roles = new ArrayList<String>();   
  51. List<String>permissions = new ArrayList<String>();  
  52.    
  53. //從數(shù)據(jù)庫中獲取當(dāng)前登錄用戶的詳細(xì)信息   
  54. Useruser = userService.getByAccount(account);  
  55.    
  56. if(user!= null){  
  57. //實體類User中包含有用戶角色的實體類信息   
  58. if(user.getRoles() != null && user.getRoles().size() > 0) {  
  59. //獲取當(dāng)前登錄用戶的角色  
  60. for(Role role : user.getRoles()) {  
  61. roles.add(role.getName());  
  62.  //實體類Role中包含有角色權(quán)限的實體類信息   
  63. if(role.getPmss() != null && role.getPmss().size() > 0) {  
  64.  //獲取權(quán)限   
  65. for(Permission pmss : role.getPmss()) {  
  66. if(!StringUtils.isEmpty(pmss.getPermission())){  
  67. permissions.add(pmss.getPermission());  
  68. }  
  69. }  
  70. }  
  71. }  
  72. }  
  73. }else{  
  74. thrownew AuthorizationException();  
  75. }  
  76.    
  77. //為當(dāng)前用戶設(shè)置角色和權(quán)限  
  78. SimpleAuthorizationInfoinfo = new SimpleAuthorizationInfo();  
  79. info.addRoles(roles);  
  80.         info.addStringPermissions(permissions);  
  81.          
  82. returninfo;  
  83.    
  84. }  
  85.    
  86. }</span>  


Shiro學(xué)習(xí)的系列文章

將 Shiro 作為應(yīng)用的權(quán)限基礎(chǔ) 一:shiro的整體架構(gòu)

將 Shiro 作為應(yīng)用的權(quán)限基礎(chǔ) 二:shiro認(rèn)證

將 Shiro 作為應(yīng)用的權(quán)限基礎(chǔ) 三:shiro授權(quán)

將 Shiro 作為應(yīng)用的權(quán)限基礎(chǔ) 四:配置說明

將 Shiro 作為應(yīng)用的權(quán)限基礎(chǔ) 五:SpringMVC+Apache Shiro+JPAhibernate)整合配置

將 Shiro 作為應(yīng)用的權(quán)限基礎(chǔ) 六:源碼以及下載地址

 


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多