前言
在學習授權前,先推薦一篇RBAC 文章,希望大家看看,這樣更有利於理解授權的概念和操作。
在這裏我簡單的說一下 RBAC的概念:Shiro授權(權限控制)實現是居於RBAC而實現的
誰(user)扮演什麼角色(role), 可以做什麼事情(permission)
授權
- 授權實質上就是訪問控制 - 控制用戶能夠訪問應用中的哪些內容,比如資源、Web 頁面等等。
- 多數用戶執行訪問控制是通過使用諸如角色和權限這類概念完成的。也就是說,通常用戶允許或不允許做的事情是根據分配給他們的角色或權限決定的。
- 那麼,通過檢查這些角色和權限,你的應用程序就可以控制哪些功能是可以暴露的。
簡單說 :授權,即訪問控制,控制誰能訪問哪些資源。主體進行身份認證後需要分配權限方可訪問系統的資源,對於某些資源沒有權限是無法訪問的。
授權方式
Shiro支持三種方式的授權
1、編程式:通過寫if/else 授權代碼塊完成:
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有權限
} else {
//無權限
}
2、註解式:通過在執行的Java方法上放置相應的註解完成
@RequiresRoles("admin")
public void hello() {
//有權限
}
3、JSP標籤:在JSP 頁面通過相應的標籤完成
<shiro:hasRole name="admin">
<!— 有權限—>
</shiro:hasRole>
使用授權 .ini
完成授權
角色測試
1、配置ini文件
2、加載配置文件,測試用戶是否擁有角色
@Test
public void testHasRow(){
//1、創建SecurityManager工廠,IniSecurityManagerFactory可以從ini文件中初始化SecurityManager環境
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");
//2、,創建Security通過工廠對象Manger對象
SecurityManager securityManager = factory.getInstance();
//3、將securityManager設置到運行環境中,讓系統隨時隨地訪問securityManager
SecurityUtils.setSecurityManager(securityManager);
//4、創建當前登錄主體
Subject subject = SecurityUtils.getSubject();
//5、收集主體登錄的身份/憑證,即賬號密碼
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666");
//6、主體登錄
subject.login(token);
//7、判斷登錄是否成功
System.out.println("驗證登錄是否成功:"+subject.isAuthenticated());
//判斷當前用戶是否擁有某個角色:返回true表示擁有,false表示沒有
System.out.println(subject.isPermitted("user:delete"));
//判斷當前用戶是否擁有某個角色:返回true表示全部擁有,false表示不全部沒有
System.out.println(subject.isPermittedAll("user:list","user:delete"));
//判斷當前用戶是否擁有某個角色:返回Boolean數組true表示有,false表示沒有
System.out.println(Arrays.toString(subject.isPermitted("user:list","user:delete")));
//判斷當前用戶是否擁有某個角色:沒有返回值,如果有不做任何操作,如果不是報異常
subject.checkRole("role1");
//判斷當前用戶是否擁有一些角色
subject.checkRoles("role1","role2");
}
權限測試
@Test
public void testHasRow(){
//1、創建SecurityManager工廠,IniSecurityManagerFactory可以從ini文件中初始化SecurityManager環境
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");
//2、,創建Security通過工廠對象Manger對象
SecurityManager securityManager = factory.getInstance();
//3、將securityManager設置到運行環境中,讓系統隨時隨地訪問securityManager
SecurityUtils.setSecurityManager(securityManager);
//4、創建當前登錄主體
Subject subject = SecurityUtils.getSubject();
//5、收集主體登錄的身份/憑證,即賬號密碼
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666");
//6、主體登錄
subject.login(token);
//7、判斷登錄是否成功
System.out.println("驗證登錄是否成功:"+subject.isAuthenticated());
//8、戶用認證狀態
Boolean isAuthenticated = subject.isAuthenticated();
System.out.println("用戶認證狀態:" + isAuthenticated);
//是否有某一個權限
System.out.println("用戶是否擁有一個權限:" + subject.isPermitted("user:create"));
//是否有多個權限
System.out.println("用戶是否擁有多個權限:" + subject.isPermittedAll("user:create","user:update"));
//權限檢查,如果沒有就跑出異常
//subject.checkPermission("user:delete");
//subject.checkPermissions("user:create","user:delete");
//是否具備編號爲1的user資源進行delete操作
//subject.checkPermission("user:delete:1");
}
自定義 Realm 實現權限控制
自定義的權限控制,可以查看 自定義Realm
在這裏說一下概念 權限表達式定義
在ini文件中用戶、角色、權限的配置規則是:“用戶名=密碼,角色1,角色2…” “角色=權限1,權限2…”,首先根據用戶名找角色,再根據角色找權限,角色是權限集合。
權限字符串的規則是:“資源標識符:操作:資源實例標識符”,意思是對哪個資源的哪個實例具有什麼操作,“:”是資源/操作/實例的分割符,權限字符串也可以使用 *
通配符。