復習
什么是權限管理?
權限管理是系統的安全范濤, 要求必須是合法用戶才能訪問系統(用戶認證), 且必須具有該資源的訪問權限才可以訪問資源(授權).
認證: 對用戶身份校驗,要求必須是合法用戶才能訪問系統.
授權: 訪問控制, 必須具有該資源的訪問權限才能訪問該資源.
權限模型: 標準權限數據模型包括:用戶,角色,權限(包括資源和權限),用戶角色關系,角色權限關系.
權限分配: 用過 UI 界面方便給用戶分配權限, 對上邊權限模型進行增刪改查操作.
權限控制:
????基于角色的權限控制: 根據角色判斷是否有操作權限, 因為角色可能要隨時發生變化, 所以當角色發生變化時, 我們需要修改系統代碼. 這也就意味著系統可維護性不強.
????基于組員的權限控制: 根據資源判斷是否有操作權限, 因為當我們開發完系統后, 一些 URL 是很少發生變化的, 也就是說不管角色怎么變化,這些 URL 是不變的,所以系統的可維護性強.
權限管理的解決方案:
????對于粗顆粒權限管理,建議在系統的架構層面解決.
比如當我們用戶認證后,獲取用戶的菜單, 不同的用戶有不同的菜單.也就是說對資源進行權限管理.
????對細顆粒權限管理,建議在系統業務層進行處理.
比如當我們要修改或刪除某條信息的時候, 不判斷是否有權限.
基于 URL 的權限管理(掌握):
????使用 web 應用中filter 來實現, 用戶請求 url, 通過 filter 攔截,判斷用戶身份是否合法(用戶認證), 再判斷請求地址是否是用戶權限范圍內的 url(授權).
Shiro 授權流程
授權方式
Shiro 支持三種授權的權限:
編程式: 通過編寫 if/else 權限代碼塊完成
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole("admin")){
//有權限
} else {
//無權限
}
注解式: 通過在執行的 Java 方法上放置相應的注解完成
@RequiresRoles("admin")
public void hello(){
//有權限
}
jsp/GSP 標簽:在 jsp/gsp 頁面通過相應的標簽完成
<shiro:hasRole name="admin">
<!-- 有權限 -->
</shiro:hasRole>
授權入門程序
** 創建 shiro-permission.ini 文件**
#用戶
[users]
#用戶 zhang 密碼是123,此用戶具有role1和role2兩個角色
zhangsan=123,role1,role2
wang=123,role2
#角色
[roles]
# 角色role1對資源 user 用于 create 和 update 權限.
role1=user:create,user:update
role2=user:create,user:delete
role3=user:create
權限標識符規則: 資源:操作:實例
例如user:create:01
表示對用戶資源的01實例進行 create 操作.
例如user:create
表示對用戶資源進行 create 操作.相當于``user:create:*```
具體實現
// 角色授權、資源授權測試
@Test
public void testAuthorization() {
// 創建SecurityManager工廠
Factory<SecurityManager> factory = new IniSecurityManagerFactory(
"classpath:shiro-permission.ini");
// 創建SecurityManager
SecurityManager securityManager = factory.getInstance();
// 將SecurityManager設置到系統運行環境,和spring后將SecurityManager配置spring容器中,一般單例管理
SecurityUtils.setSecurityManager(securityManager);
// 創建subject
Subject subject = SecurityUtils.getSubject();
// 創建token令牌
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
"123");
// 執行認證
try {
subject.login(token);
} catch (AuthenticationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("認證狀態:" + subject.isAuthenticated());
// 認證通過后執行授權
// 基于角色的授權
// hasRole傳入角色標識
boolean ishasRole = subject.hasRole("role1");
System.out.println("單個角色判斷" + ishasRole);
// hasAllRoles是否擁有多個角色
boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1",
"role2", "role3"));
System.out.println("多個角色判斷" + hasAllRoles);
// 使用check方法進行授權,如果授權不通過會拋出異常
// subject.checkRole("role13");
// 基于資源的授權
// isPermitted傳入權限標識符
boolean isPermitted = subject.isPermitted("user:create:1");
System.out.println("單個權限判斷" + isPermitted);
boolean isPermittedAll = subject.isPermittedAll("user:create:1",
"user:delete");
System.out.println("多個權限判斷" + isPermittedAll);
// 使用check方法進行授權,如果授權不通過會拋出異常
// subject.checkPermission("items:create:1");
}