(轉)shiro權限框架詳解05-shiro授權


http://blog.csdn.net/facekbook/article/details/54910606

本文介紹

  • 授權流程
  • 授權方式
  • 授權測試
  • 自定義授權realm

授權流程

開始構造SecurityManager環境subject.isPermitted()授權securityManager.isPermitted()執行授權Authorizer執行授權Realm根據身份獲取資源權限信息結束

授權方式

Shiro支持三種方式的授權:

  • 編程式:通過寫if/else授權代碼塊完成。
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole("admin")){ //有權限 }else{ //沒有權限 }

 

  • 注解式:通過在執行的Java方法上放置相應的注解完成。
@RequiresRole("admin") public void hell(){ //有權限 }

 

  • JSP標簽:在Jsp頁面通過相應的標簽完成:
<shiro:hasRole name="admin"> <!--有權限--> </shiro:hasRole>

 

授權測試

創建ini配置文件

在classpath路徑下創建shiro-permission.ini文件,內容如下:

[users]
#用戶zhangsan的密碼是123,此用戶具有role1和role2兩個角色
zhangsan=123,role1,role2
lisi=123,role2

[roles]
#角色role1對資源user擁有create、update權限 role1=user:create,user:update #角色role2對資源user擁有create、delete權限 role2=user:create,user.delete #角色role3對資源user擁有create權限 role3=user:create

 

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

權限字符串規則

權限字符串的規則是:”資源標識符:操作:資源實例標識符”,意思是對哪個資源的哪個實例具有什么操作,”:”是資源/操作/實例的分割符,權限字符串也可以使用*通配符。 
例子: 
用戶創建權限:user:create或user:create:* 
用戶修改實例001的權限:user:update:001 
用戶實例001的所有權限:user:*:001

測試代碼

    @Test public void testPermission() { // 構建SecurityManager工廠,IniSecurityManagerFactory可以從ini文件中初始化SecurityManager環境 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini"); // 通過工廠創建SecurityManager SecurityManager securityManager = factory.getInstance(); // 將SecurityManager設置到運行環境中 SecurityUtils.setSecurityManager(securityManager); //創建一個Subject實例,該實例認證需要使用上面創建的SecurityManager Subject subject = SecurityUtils.getSubject(); //創建token令牌,賬號和密碼是ini文件中配置的 //AuthenticationToken token = new UsernamePasswordToken("zhangsan", "123");//賬號密碼正確token 角色是 role1,role2 AuthenticationToken token = new UsernamePasswordToken("lisi", "123");//lisi賬號的token 角色是role3 /** * role1=user:create,user:update role2=user:create,user.delete role3=user:create */ try { //用戶登錄 subject.login(token); } catch (AuthenticationException e) { e.printStackTrace(); } //用戶認證狀態 Boolean isAuthenticated = subject.isAuthenticated(); System.out.println("用戶認證狀態:"+isAuthenticated);//輸出true //用戶授權檢測 //是否擁有一個角色 System.out.println("是否擁有一個角色:"+subject.hasRole("role1")); //是否擁有多個角色 System.out.println("是否擁有多個角色:"+subject.hasAllRoles(Arrays.asList("role1","role2"))); //檢測權限 try { subject.checkPermission("user:create"); } catch (AuthorizationException e) { e.printStackTrace(); } try { subject.checkPermissions("user:create","user.delete"); } catch (AuthorizationException e) { e.printStackTrace(); } }

 

基於角色的授權

//是否擁有一個角色 System.out.println("是否擁有一個角色:"+subject.hasRole("role1")); //是否擁有多個角色 System.out.println("是否擁有多個角色:"+subject.hasAllRoles(Arrays.asList("role1","role2")));

 

對應的check方法:

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

 

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

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

 

基於資源授權

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

 

對應的check方法:

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

 

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

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

 

自定義realm

shiro認證那篇博客中編寫的自定義realm類中有一個doGetAuthorizationInfo 方法,此方法需要完成:根據用戶身份信息從數據庫查詢權限字符串,由shiro進行授權。

realm代碼

/** * 授權方法 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { //后去身份信息,這個字段就是前面的username String username = (String)principals.getPrimaryPrincipal(); //模擬通過身份信息獲取所有權限 List<String> permissions = new ArrayList<>(); permissions.add("user:create"); permissions.add("user:delete"); //將權限信息封裝到AuthorizationInfo中,並返回 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); authorizationInfo.addStringPermissions(permissions); return authorizationInfo; }

 

shiro-realm.ini文件

需要使用這個配置文件。

測試代碼

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

授權執行流程

1、 執行subject.isPermitted(“user:create”) 
2、 securityManager通過ModularRealmAuthorizer進行授權 
3、 ModularRealmAuthorizer調用realm獲取權限信息 
4、 ModularRealmAuthorizer再通過permissionResolver解析權限字符串,校驗是否匹配

該文章涉及的代碼

代碼地址


免責聲明!

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



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