java技術(shù)研究

          導(dǎo)航

          <2013年9月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          隨筆分類

          隨筆檔案

          統(tǒng)計

          留言簿(3)

          閱讀排行榜

          評論排行榜

          Apache Shiro 使用手冊(三)Shiro 授權(quán)(轉(zhuǎn))

          博客分類: 
        1. 開發(fā)

        2. 安全框架Shiro 
          授權(quán)即訪問控制,它將判斷用戶在應(yīng)用程序中對資源是否擁有相應(yīng)的訪問權(quán)限。 
          如,判斷一個用戶有查看頁面的權(quán)限,編輯數(shù)據(jù)的權(quán)限,擁有某一按鈕的權(quán)限,以及是否擁有打印的權(quán)限等等。 

          一、授權(quán)的三要素 

          授權(quán)有著三個核心元素:權(quán)限、角色和用戶。 

          權(quán)限 
          權(quán)限是Apache Shiro安全機(jī)制最核心的元素。它在應(yīng)用程序中明確聲明了被允許的行為和表現(xiàn)。一個格式良好好的權(quán)限聲明可以清晰表達(dá)出用戶對該資源擁有的權(quán)限。 
          大多數(shù)的資源會支持典型的CRUD操作(create,read,update,delete),但是任何操作建立在特定的資源上才是有意義的。因此,權(quán)限聲明的根本思想就是建立在資源以及操作上。 
          而我們通過權(quán)限聲明僅僅能了解這個權(quán)限可以在應(yīng)用程序中做些什么,而不能確定誰擁有此權(quán)限。 
          于是,我們就需要在應(yīng)用程序中對用戶和權(quán)限建立關(guān)聯(lián)。 
          通常的做法就是將權(quán)限分配給某個角色,然后將這個角色關(guān)聯(lián)一個或多個用戶。 

          權(quán)限聲明及粒度 
          Shiro權(quán)限聲明通常是使用以冒號分隔的表達(dá)式。就像前文所講,一個權(quán)限表達(dá)式可以清晰的指定資源類型,允許的操作,可訪問的數(shù)據(jù)。同時,Shiro權(quán)限表達(dá)式支持簡單的通配符,可以更加靈活的進(jìn)行權(quán)限設(shè)置。 
          下面以實(shí)例來說明權(quán)限表達(dá)式。 
          可查詢用戶數(shù)據(jù) 
          User:view 
          可查詢或編輯用戶數(shù)據(jù) 
          User:view,edit 
          可對用戶數(shù)據(jù)進(jìn)行所有操作 
          User:* 或 user 
          可編輯id為123的用戶數(shù)據(jù) 
          User:edit:123 

          角色 
          Shiro支持兩種角色模式: 
          1、傳統(tǒng)角色:一個角色代表著一系列的操作,當(dāng)需要對某一操作進(jìn)行授權(quán)驗(yàn)證時,只需判斷是否是該角色即可。這種角色權(quán)限相對簡單、模糊,不利于擴(kuò)展。 
          2、權(quán)限角色:一個角色擁有一個權(quán)限的集合。授權(quán)驗(yàn)證時,需要判斷當(dāng)前角色是否擁有該權(quán)限。這種角色權(quán)限可以對該角色進(jìn)行詳細(xì)的權(quán)限描述,適合更復(fù)雜的權(quán)限設(shè)計。 
          下面將詳細(xì)描述對兩種角色模式的授權(quán)實(shí)現(xiàn)。 

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

          Shiro支持三種方式實(shí)現(xiàn)授權(quán)過程: 
          • 編碼實(shí)現(xiàn)
          • 注解實(shí)現(xiàn)
          • JSP Taglig實(shí)現(xiàn)
          1、基于編碼的授權(quán)實(shí)現(xiàn) 

          1.1基于傳統(tǒng)角色授權(quán)實(shí)現(xiàn) 
          當(dāng)需要驗(yàn)證用戶是否擁有某個角色時,可以調(diào)用Subject 實(shí)例的hasRole*方法驗(yàn)證。 
          Java代碼  收藏代碼
          1. Subject currentUser = SecurityUtils.getSubject();  
          2. if (currentUser.hasRole("administrator")) {  
          3.     //show the admin button  
          4. else {  
          5.     //don't show the button?  Grey it out?  
          6. }  

          相關(guān)驗(yàn)證方法如下: 
          Subject方法描述
          hasRole(String roleName)當(dāng)用戶擁有指定角色時,返回true
          hasRoles(List<String> roleNames)按照列表順序返回相應(yīng)的一個boolean值數(shù)組
          hasAllRoles(Collection<String> roleNames)如果用戶擁有所有指定角色時,返回true

          斷言支持 
          Shiro還支持以斷言的方式進(jìn)行授權(quán)驗(yàn)證。斷言成功,不返回任何值,程序繼續(xù)執(zhí)行;斷言失敗時,將拋出異常信息。使用斷言,可以使我們的代碼更加簡潔。 
          Java代碼  收藏代碼
          1. Subject currentUser = SecurityUtils.getSubject();  
          2. //guarantee that the current user is a bank teller and  
          3. //therefore allowed to open the account:  
          4. currentUser.checkRole("bankTeller");  
          5. openBankAccount();  

          斷言的相關(guān)方法: 
          Subject方法描述
          checkRole(String roleName)斷言用戶是否擁有指定角色
          checkRoles(Collection<String> roleNames)斷言用戶是否擁有所有指定角色
          checkRoles(String... roleNames)對上一方法的方法重載

          1.2 基于權(quán)限角色授權(quán)實(shí)現(xiàn) 
          相比傳統(tǒng)角色模式,基于權(quán)限的角色模式耦合性要更低些,它不會因角色的改變而對源代碼進(jìn)行修改,因此,基于權(quán)限的角色模式是更好的訪問控制方式。 
          它的代碼實(shí)現(xiàn)有以下幾種實(shí)現(xiàn)方式: 
          1、基于權(quán)限對象的實(shí)現(xiàn) 
          創(chuàng)建org.apache.shiro.authz.Permission的實(shí)例,將該實(shí)例對象作為參數(shù)傳遞給Subject.isPermitted()進(jìn)行驗(yàn)證。 
          Java代碼  收藏代碼
          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. }  
          8. Permission printPermission = new PrinterPermission("laserjet4400n", "print");  
          9. Subject currentUser = SecurityUtils.getSubject();  
          10. if (currentUser.isPermitted(printPermission)) {  
          11.     //show the Print button  
          12. else {  
          13.     //don't show the button?  Grey it out?  
          14. }  

          相關(guān)方法如下: 
          Subject方法描述
          isPermitted(Permission p)Subject擁有制定權(quán)限時,返回treu
          isPermitted(List<Permission> perms)返回對應(yīng)權(quán)限的boolean數(shù)組
          isPermittedAll(Collection<Permission> perms)Subject擁有所有制定權(quán)限時,返回true

          2、 基于字符串的實(shí)現(xiàn) 
          相比笨重的基于對象的實(shí)現(xiàn)方式,基于字符串的實(shí)現(xiàn)便顯得更加簡潔。 
          Java代碼  收藏代碼
          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)支持的實(shí)現(xiàn)方式。 
          這里分別代表了 資源類型:操作:資源ID 

          類似基于對象的實(shí)現(xiàn)相關(guān)方法,基于字符串的實(shí)現(xiàn)相關(guān)方法: 
          isPermitted(String perm)、isPermitted(String... perms)、isPermittedAll(String... perms) 

          基于權(quán)限對象的斷言實(shí)現(xiàn) 
          Java代碼  收藏代碼
          1. Subject currentUser = SecurityUtils.getSubject();  
          2. //guarantee that the current user is permitted  
          3. //to open a bank account:  
          4. Permission p = new AccountPermission("open");  
          5. currentUser.checkPermission(p);  
          6. openBankAccount();  

          基于字符串的斷言實(shí)現(xiàn) 
          Java代碼  收藏代碼
          1. Subject currentUser = SecurityUtils.getSubject();  
          2. //guarantee that the current user is permitted  
          3. //to open a bank account:  
          4. currentUser.checkPermission("account:open");  
          5. openBankAccount();  

          斷言實(shí)現(xiàn)的相關(guān)方法 
          Subject方法說明
          checkPermission(Permission p)斷言用戶是否擁有制定權(quán)限
          checkPermission(String perm)斷言用戶是否擁有制定權(quán)限
          checkPermissions(Collection<Permission> perms)斷言用戶是否擁有所有指定權(quán)限
          checkPermissions(String... perms)斷言用戶是否擁有所有指定權(quán)限

          2、基于注解的授權(quán)實(shí)現(xiàn) 
          Shiro注解支持AspectJ、Spring、Google-Guice等,可根據(jù)應(yīng)用進(jìn)行不同的配置。 

          相關(guān)的注解: 
          @ RequiresAuthentication 
          可以用戶類/屬性/方法,用于表明當(dāng)前用戶需是經(jīng)過認(rèn)證的用戶。 
          Java代碼  收藏代碼
          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. }  

          @ RequiresGuest 
          表明該用戶需為”guest”用戶 

          @ RequiresPermissions 
          當(dāng)前用戶需擁有制定權(quán)限 
          Java代碼  收藏代碼
          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. }  

          @RequiresRoles 
          當(dāng)前用戶需擁有制定角色 

          @ RequiresUser 
          當(dāng)前用戶需為已認(rèn)證用戶或已記住用戶 

          3、基于JSP  TAG的授權(quán)實(shí)現(xiàn) 
          Shiro提供了一套JSP標(biāo)簽庫來實(shí)現(xiàn)頁面級的授權(quán)控制。 
          在使用Shiro標(biāo)簽庫前,首先需要在JSP引入shiro標(biāo)簽: 
          Java代碼  收藏代碼
          1. <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>  

          下面一一介紹Shiro的標(biāo)簽: 
          guest標(biāo)簽 
          驗(yàn)證當(dāng)前用戶是否為“訪客”,即未認(rèn)證(包含未記住)的用戶 
          Xml代碼  收藏代碼
          1. <shiro:guest>  
          2.     Hi there!  Please <a href="login.jsp">Login</a> or <a href="signup.jsp">Signup</a> today!  
          3. </shiro:guest>  

          user標(biāo)簽 
          認(rèn)證通過或已記住的用戶 
          Xml代碼  收藏代碼
          1. <shiro:user>  
          2.     Welcome back John!  Not John? Click <a href="login.jsp">here<a> to login.  
          3. </shiro:user>  

          authenticated標(biāo)簽 
          已認(rèn)證通過的用戶。不包含已記住的用戶,這是與user標(biāo)簽的區(qū)別所在。 
          Xml代碼  收藏代碼
          1. <shiro:authenticated>  
          2.     <a href="updateAccount.jsp">Update your contact information</a>.  
          3. </shiro:authenticated>  

          notAuthenticated標(biāo)簽 
          未認(rèn)證通過用戶,與authenticated標(biāo)簽相對應(yīng)。與guest標(biāo)簽的區(qū)別是,該標(biāo)簽包含已記住用戶。 
          Xml代碼  收藏代碼
          1. <shiro:notAuthenticated>  
          2.     Please <a href="login.jsp">login</a> in order to update your credit card information.  
          3. </shiro:notAuthenticated>  

          principal 標(biāo)簽 
          輸出當(dāng)前用戶信息,通常為登錄帳號信息 
          Xml代碼  收藏代碼
          1. Hello, <shiro:principal/>, how are you today?  

          hasRole標(biāo)簽 
          驗(yàn)證當(dāng)前用戶是否屬于該角色 
          Xml代碼  收藏代碼
          1. <shiro:hasRole name="administrator">  
          2.     <a href="admin.jsp">Administer the system</a>  
          3. </shiro:hasRole>  

          lacksRole標(biāo)簽 
          與hasRole標(biāo)簽邏輯相反,當(dāng)用戶不屬于該角色時驗(yàn)證通過 
          Xml代碼  收藏代碼
          1. <shiro:lacksRole name="administrator">  
          2.     Sorry, you are not allowed to administer the system.  
          3. </shiro:lacksRole>  

          hasAnyRole標(biāo)簽 
          驗(yàn)證當(dāng)前用戶是否屬于以下任意一個角色。 
          Xml代碼  收藏代碼
          1. <shiro:hasAnyRoles name="developer, project manager, administrator">  
          2.     You are either a developer, project manager, or administrator.  
          3. </shiro:lacksRole>  

          hasPermission標(biāo)簽 
          驗(yàn)證當(dāng)前用戶是否擁有制定權(quán)限 
          Xml代碼  收藏代碼
          1. <shiro:hasPermission name="user:create">  
          2.     <a href="createUser.jsp">Create a new User</a>  
          3. </shiro:hasPermission>  

          lacksPermission標(biāo)簽 
          與hasPermission標(biāo)簽邏輯相反,當(dāng)前用戶沒有制定權(quán)限時,驗(yàn)證通過 
          Xml代碼  收藏代碼
          1. <shiro:hasPermission name="user:create">  
          2.     <a href="createUser.jsp">Create a new User</a>  
          3. </shiro:hasPermission>  


          三、Shiro授權(quán)的內(nèi)部處理機(jī)制 
           
          1、在應(yīng)用程序中調(diào)用授權(quán)驗(yàn)證方法(Subject的isPermitted*或hasRole*等) 
          2、Sbuject的實(shí)例通常是DelegatingSubject類(或子類)的實(shí)例對象,在認(rèn)證開始時,會委托應(yīng)用程序設(shè)置的securityManager實(shí)例調(diào)用相應(yīng)的isPermitted*或hasRole*方法。 
          3、接下來SecurityManager會委托內(nèi)置的Authorizer的實(shí)例(默認(rèn)是ModularRealmAuthorizer 類的實(shí)例,類似認(rèn)證實(shí)例,它同樣支持一個或多個Realm實(shí)例認(rèn)證)調(diào)用相應(yīng)的授權(quán)方法。 
          4、每一個Realm將檢查是否實(shí)現(xiàn)了相同的 Authorizer 接口。然后,將調(diào)用Reaml自己的相應(yīng)的授權(quán)驗(yàn)證方法。 

          當(dāng)使用多個Realm時,不同于認(rèn)證策略處理方式,授權(quán)處理過程中: 
          1、當(dāng)調(diào)用Realm出現(xiàn)異常時,將立即拋出異常,結(jié)束授權(quán)驗(yàn)證。 
          2、只要有一個Realm驗(yàn)證成功,那么將認(rèn)為授權(quán)成功,立即返回,結(jié)束認(rèn)證。 

          轉(zhuǎn)自http://kdboy.iteye.com/blog/1155450

          posted on 2013-09-05 17:04 小秦 閱讀(362) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 类乌齐县| 枝江市| 江永县| 都昌县| 新龙县| 东乡族自治县| 从江县| 乡城县| 石楼县| 会泽县| 沧源| 信丰县| 稻城县| 余庆县| 白河县| 灌阳县| 六枝特区| 读书| 房山区| 尼玛县| 四会市| 南部县| 怀远县| 遂昌县| 内丘县| 彭山县| 鸡西市| 湟中县| 全椒县| 松江区| 九龙县| 根河市| 平阴县| 武定县| 景谷| 新河县| 突泉县| 宣城市| 济源市| 罗平县| 凌云县|