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