
一. Shiro是什么
Shiro是一個Java平台的開源權限框架,用於認證和訪問授權。具體來說,滿足對如下元素的支持:
- 用戶,角色,權限(僅僅是操作權限,數據權限必須與業務需求緊密結合),資源(url)。
- 用戶分配角色,角色定義權限。
- 訪問授權時支持角色或者權限,並且支持多級的權限定義。
Q:對組的支持?
A:shiro默認不支持對組設置權限。
Q:是否可以滿足對組進行角色分配的需求?
A:擴展Realm,可以支持對組進行分配角色,其實就是給該組下的所有用戶分配權限。
Q:對數據權限的支持? 在業務系統中定義?
A:shiro僅僅實現對操作權限的控制,用於在前端控制元素隱藏或者顯示,以及對資源訪問權限進行檢查。數據權限與具體的業務需求緊密關聯,shiro本身無法實現對數據權限的控制。
Q:動態權限分配?
A:擴展org.apache.shiro.realm.Realm,支持動態權限分配。
Q:與Spring集成?
A:可以支持與Spring集成,shiro還支持jsp標簽。
二. 系統架構
在shiro架構中,有3個最主要的組件:Subject,SecurityManager,Realm。
Subject本質上就是當前訪問用戶的抽象描述。
SecurityManager是Shiro架構中最核心的組件,通過它可以協調其他組件完成用戶認證和授權。實際上,SecurityManager就是Shiro框架的控制器。
Realm定義了訪問數據的方式,用來連接不同的數據源,如:LDAP,關系數據庫,配置文件等等。
三. 如何使用Shiro
Shiro作為一個完善的權限框架,可以應用在多種需要進行身份認證和訪問授權的場景,例如:
1. 在獨立應用中使用shiro
http://www.cnblogs.com/nuccch/p/6780550.html 細說shiro之三:在獨立應用中使用shiro
2. 在web應用中使用shiro
http://www.cnblogs.com/nuccch/p/6785167.html 細說shiro之四:在web應用中使用shiro
3. 在spring框架中集成shiro
http://www.cnblogs.com/nuccch/p/6790408.html 細說shiro之五:在spring框架中集成shiro
四. Shiro原理
1. 認證
通過調用Subject.login(token)方法開始用戶認證流程。
Subject currentUser = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, password); token.setRememberMe(true); try { currentUser.login(token); } catch (UnknownAccountException e) { logger.error(String.format("user not found: %s", username), e); // 用戶不存在 } catch (IncorrectCredentialsException e) { logger.error(String.format("incorrent credentials: %s", username), e); // 密碼不正確 } catch (ConcurrentAccessException e) { logger.error(String.format("user has been authenticated: %s", username), e); // 用戶重復登錄 } catch (AccountException e) { logger.error(String.format("account except: %s", username), e); // 其他賬戶異常 }
shiro用戶認證時序圖:
2. 授權
shiro訪問授權有3種實現方式:api調用,java注解,jsp標簽。
(1)在獨立應用程序中訪問授權通過api調用實現
String role = "schwartz"; Subject currentUser = SecurityUtils.getSubject(); if(currentUser.hasRole(role)) { //用戶屬於角色schwartz }else{ //用戶不屬於角色schwartz }
(2)在spring框架中可以通過java注解
@RequiresPermissions(value={"log:manage:*"})
public ModelAndView home(HttpServletRequest req) {
ModelAndView mv = new ModelAndView("home");
return mv;
}
(3)在JSP頁面中還可以直接使用jsp標簽
<!-- 使用shiro標簽 --> <shiro:hasPermission name="log:manage:*"> <a href="<%=request.getContextPath()%>/user/home">操作日志審計</a><br/> </shiro:hasPermission>
shiro訪問授權時序圖:
五. 注意事項
1.org.apache.shiro.realm.jdbc.JdbcRealm如果需要在授權時開啟權限檢查,必須設置permissionsLookupEnabled為true,否則只檢查角色。
2.用戶退出登錄時,Shiro用戶必須執行logout(),必須要注銷Session信息,避免影響下一次用戶認證和授權。
SecurityUtils.getSubject().logout();
req.getSession().invalidate();
3.如果在數據庫中存儲的用戶密碼為編碼值(如MD5加密),則在發送登錄請求時傳遞的密碼參數也必須是MD5加密結果,否則認證失敗。
4.shiro框架只能控制操作權限,不能控制數據權限。數據權限與具體的業務緊密關聯,無法通過一個通用的框架完成,通常都是利用關系數據庫查詢過濾實現。
對操作權限的控制有2層含義,其一:用戶在前端只能看到對應權限的元素;其二:在后端對用戶操作進行權限檢查。
