1、三種受權方式java
一、編程式:經過寫if/else受權代碼塊完成:編程
Subject subject = SecurityUtils.getSubject(); if(subject.hasRole(「admin」)) { //有權限 } else { //無權限 }
二、註解式:經過在執行的Java方法上放置相應的註解完成:ui
@RequiresRoles("admin") public void hello() { //有權限 }
三、JSP/GSP標籤:在JSP/GSP頁面經過相應的標籤完成:code
< shiro: hasRole name = "admin" > < !— 有權限 — > < / shiro: hasRole >
二受權對象
** 1基於角色的訪問控制(隱式角色)**資源
Shiro提供了hasRole/hasRole用於判斷用戶是否擁有某個角色/某些權限,checkRole/checkRoles和hasRole/hasAllRoles不一樣的地方是它在判斷爲假的狀況下會拋出UnauthorizedException異常。具體用法以下:字符串
//判斷擁有角色:role1 Assert.assertTrue(subject().hasRole("role1")); //判斷擁有角色:role1 and role2 Assert.assertTrue(subject().hasAllRoles(Arrays.asList("role1", "role2"))); //判斷擁有角色:role1 and role2 and !role3 boolean[] result = subject().hasRoles(Arrays.asList("role1", "role2", "role3")); Assert.assertEquals(true, result[0]); Assert.assertEquals(true, result[1]); Assert.assertEquals(false, result[2]); //斷言擁有角色:role1 subject().checkRole("role1"); //斷言擁有角色:role1 and role3 失敗拋出異常 subject().checkRoles("role1", "role3");
總結:隱式角色缺點就是若是不少地方進行了角色判斷,可是有一天不須要了那麼就須要修改相應代碼把全部相關的地方進行刪除;這就是粗粒度形成的問題get
3基於權限的訪問控制(顯示角色)it
Shiro提供了isPermitted和isPermittedAll用於判斷用戶是否擁有某個權限或全部權限,checkPermission/checkPermissions和isPermitted和isPermittedAll不一樣的地方是它在判斷爲假的狀況下會拋出UnauthorizedException異常。具體用法以下:io
//判斷擁有權限:user:create Assert.assertTrue(subject().isPermitted("user:create")); //判斷擁有權限:user:update and user:delete Assert.assertTrue(subject().isPermittedAll("user:update", "user:delete")); //判斷沒有權限:user:view Assert.assertFalse(subject().isPermitted("user:view")); //斷言擁有權限:user:create subject().checkPermission("user:create"); //斷言擁有權限:user:delete and user:update subject().checkPermissions("user:delete", "user:update"); //斷言擁有權限:user:view 失敗拋出異常 subject().checkPermissions("user:view");
總結:這種方式的通常規則是「資源標識符:操做」,便是資源級別的粒度;這種方式的好處就是若是要修改基本都是一個資源級別的修改,不會對其餘模塊代碼產生影響。
** 三Permission**
規則:「資源標識符:操做:對象實例ID」 即對哪一個資源的哪一個實例能夠進行什麼操做。
**一、單個資源單個權限 **
subject().checkPermissions("system:user:update");
二、單個資源多個權限
ini配置文件:
role41=system:user:update,system:user:delete
java代碼:
subject().checkPermissions("system:user:update", "system:user:delete");
以上能夠簡寫成以下所示:
ini配置文件:
role42="system:user:update,delete"
java代碼:
subject().checkPermissions("system:user:update,delete");
經過「system:user:update,delete」驗證"system:user:update, system:user:delete"是沒問題的,可是反過來是規則不成立。
** 三、單個資源所有權限**
ini配置:
role51="system:user:create,update,delete,view"
Java代碼:
subject().checkPermissions("system:user:create,delete,update:view");
以上能夠簡寫成(推薦):
ini配置:
role52=system:user:*
Java代碼:
subject().checkPermissions("system:user:*");
以上也能夠簡寫成:
ini配置:
role53=system:user
Java代碼 :
subject().checkPermissions("system:user")
經過「system:user:*」驗證「system:user:create,delete,update:view」能夠,可是反過來是不成立的
四、全部資源所有權限
ini配置:
role61=*:view
Java代碼 :
subject().checkPermissions("user:view");
system:user:view對應role5=::view
五、實例級別的權限
單個實例單個權限
ini配置:
role71=user:view:1
Java代碼 :
subject().checkPermissions("user:view:1");
單個實例多個權限
ini配置:
role72="user:update,delete:1"
Java代碼 :
subject().checkPermissions("user:delete,update:1");
或
subject().checkPermissions("user:update:1", "user:delete:1");
全部實例單個權限
ini配置:
role74=user:auth:*
Java代碼 :
subject().checkPermissions("user:auth:1", "user:auth:2");
全部實例全部權限
ini配置:
role75=user:*:*
Java代碼 :
subject().checkPermissions("user:view:1", "user:auth:2");
Shiro對權限字符串缺失部分的處理
即能夠匹配全部,不加能夠進行前綴匹配;可是如「:view」不能匹配「system:user:view」,須要使用「::view」,即後綴匹配必須指定前綴(多個冒號就須要多個來匹配)。