Shiro許可權框架之一 --------簡介
一. 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層含義,其一:使用者在前端只能看到對應許可權的元素;其二:在後端對使用者操作進行許可權檢查。