(2)shiro角色资源权限
一般在web系統權限設計中,一般分為三個維度,用戶,角色,資源,一個用戶可以擁有多個角色,比如說可以是老師,也可以是班主任,一個角色也可以擁有多個資源。
比如老師同時擁有查看班級學生和批改作業的資源,如果一個用戶有老師這個角色,那么就代表他擁有了查看班級學生和批改作業的兩個資源權限。
因為只判斷角色顆粒度太粗,而根據資源權限則比較細。
?
校驗權限代碼
在classpath下新建shiro-role.ini文件,內容如下:
代表有一個zhang的用戶,擁有role1角色(如果有多個角色,后面用逗號繼續隔開role1,role2)
role1這個角色有兩個資源,分別是user:create和user:update。
[users] zhang=123456,role1 [roles] role1=user:create,user:update測試代碼:
Factory<SecurityManager> factory =new IniSecurityManagerFactory("classpath:shiro-role.ini");//得到安全管理器SecurityManager securityManager = factory.getInstance();//將securityManager托管給SecurityUtils SecurityUtils.setSecurityManager(securityManager);Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123456");try {subject.login(token);} catch (AuthenticationException e) {e.printStackTrace();}//是否已經認證 System.out.println(subject.isAuthenticated());//校驗是否有對應的權限和資源,如果沒有則拋出對應的異常UnauthorizedExceptionsubject.checkRole("role1");subject.checkPermission("user:create");//退出subject.logout();過程沒有遇到任何錯誤,執行到了最后,但是如果你check一個zhang不存在的role或者permission,則會報UnauthorizedException。
?
身份和憑證
在登陸中,用戶需要提供principals(身份)和credentials(證明/憑證)提供給shiro來進行認證和授權。
principals可以有多個身份,但是只能有一個Primary principals,一般是登錄賬號,比如手機號。
credentials一般是密碼。
在UsernamePasswordToken的賬戶密碼就對應著身份和憑證。
?
?
subject.login()原理
當執行subject.login的時候,實際調用的是securityManager所屬的Authenticator(默認是ModularRealmAuthenticator)的doAuthenticate方法進行驗證。
?
?他會根據當前設置了幾個realm走不同的方法(后面介紹多個realms)
?最終走的realm對應的getAuthenticationInfo方法,判斷用戶賬號密碼是否正確,如果錯誤則拋出對應的異常。正確則返回一個AuthenticationInfo對象。(這里是SimpleAuthenticationInfo)
?所以后面我們自定義realms的時候就覆蓋getAuthenticationInfo這個方法即可。
?
subject.checkRole原理
當用戶調用subject.checkRole("role1")判斷用戶是否有對應的角色的時候,底層還是走的SecurityManager所屬的Authorizer的checkRole方法。
hasRole然后又走了下面的方法
最后獲取到了所有的realms,上篇文章說了java環境下使用了IniRealm,并且注入到了Authenticator(認證器)和Authorizer(授權器)的一個成員變量中。
所以getRealms就可以直接獲取到所有的realms
因為IniRealms繼承了AuthorizingRealm,而IniRealm沒有實現hasRole方法,所以會走他的繼承類AuthorizingRealm里面的hasRole來判斷是否有權限。下面就是對應的方法。
在初始化IniRealm的時候會讀取所有用戶所屬的role和permission并封裝到成員變量中,getAuthorizationInfo方法就是返回了一個AuthorizationInfo對象里面獲取了zhang所屬role和permission。
所以我們自定義realm進行授權的時候就是覆蓋了realm的getAuthorizationInfo方法,里面封裝的role和permission都是從數據庫查詢出來的。
?
最后進行checkRole就很容易看懂了。
?
如果返回false,則Authorizer會拋出UnauthorizedException授權失敗異常。
?
github地址
https://github.com/cmniefei/shiroparent
?
轉載于:https://www.cnblogs.com/nfcm/p/9875657.html
總結
以上是生活随笔為你收集整理的(2)shiro角色资源权限的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTTPS通信的C++实现
- 下一篇: [翻译] Qt QFtp功能无法被Qt