日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

SpringBoot+Shiro学习(四):Realm授权

發(fā)布時(shí)間:2023/12/6 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringBoot+Shiro学习(四):Realm授权 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

上一節(jié)我們講了自定義Realm中的認(rèn)證(doGetAuthenticationInfo),這節(jié)我們繼續(xù)講另一個(gè)方法doGetAuthorizationInfo授權(quán)

授權(quán)流程

流程如下:

  • 首先調(diào)用Subject.isPermitted/hasRole接口,其會(huì)委托給SecurityManager,而SecurityManager接著會(huì)委托給Authorizer
  • Authorizer是真正的授權(quán)者,如果我們調(diào)用如isPermitted(“user:view”),其首先會(huì)通過PermissionResolver把字符串轉(zhuǎn)換成相應(yīng)的Permission實(shí)例;
  • 在進(jìn)行授權(quán)之前,其會(huì)調(diào)用相應(yīng)的Realm獲取Subject相應(yīng)的角色/權(quán)限用于匹配傳入的角色/權(quán)限;
  • Authorizer會(huì)判斷Realm的角色/權(quán)限是否和傳入的匹配,如果有多個(gè)Realm,會(huì)委托給ModularRealmAuthorizer進(jìn)行循環(huán)判斷,如果匹配如isPermitted*/hasRole*會(huì)返回true,否則返回false表示授權(quán)失敗。
  • ModularRealmAuthorizer進(jìn)行多Realm匹配流程:

  • 首先檢查相應(yīng)的Realm是否實(shí)現(xiàn)了實(shí)現(xiàn)了Authorizer;
  • 如果實(shí)現(xiàn)了Authorizer,那么接著調(diào)用其相應(yīng)的isPermitted*/hasRole*接口進(jìn)行匹配;
  • 如果有一個(gè)Realm匹配那么將返回true,否則返回false。
  • 如果Realm進(jìn)行授權(quán)的話,應(yīng)該繼承AuthorizingRealm,其流程是:
    1.1、如果調(diào)用hasRole,則直接獲取AuthorizationInfo.getRoles()與傳入的角色比較即可;
    1.2、首先如果調(diào)用如isPermitted(“user:view”),首先通過PermissionResolver將權(quán)限字符串轉(zhuǎn)換成相應(yīng)的Permission實(shí)例,默認(rèn)使用WildcardPermissionResolver,即轉(zhuǎn)換為通配符的WildcardPermission;
    2、通過AuthorizationInfo.getObjectPermissions()得到Permission實(shí)例集合;通過AuthorizationInfo. getStringPermissions()得到字符串集合并通過PermissionResolver解析為Permission實(shí)例;然后獲取用戶的角色,并通過RolePermissionResolver解析角色對(duì)應(yīng)的權(quán)限集合(默認(rèn)沒有實(shí)現(xiàn),可以自己提供);
    3、接著調(diào)用Permission. implies(Permission p)逐個(gè)與傳入的權(quán)限比較,如果有匹配的則返回true,否則false。


    先看一段簡(jiǎn)單的授權(quán)方法重寫

    @Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//獲取用戶名String username = (String) principals.getPrimaryPrincipal();//此處從數(shù)據(jù)庫(kù)獲取該用戶的角色Set<String> roles = getRolesByUserName(username);//此處從數(shù)據(jù)庫(kù)獲取該角色的權(quán)限Set<String> permissions = getPermissionsByUserName(username);//放到info里返回SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();info.setStringPermissions(permissions);info.setRoles(roles);return info;} 復(fù)制代碼

    PrincipalCollection

    因?yàn)槲覀兛梢栽赟hiro中同時(shí)配置多個(gè)Realm,所以呢身份信息可能就有多個(gè);因此其提供了PrincipalCollection用于聚合這些身份信息:

    public?interface?PrincipalCollection?extends?Iterable,?Serializable?{??Object?getPrimaryPrincipal();?//得到主要的身份??<T>?T?oneByType(Class<T>?type);?//根據(jù)身份類型獲取第一個(gè)??<T>?Collection<T>?byType(Class<T>?type);?//根據(jù)身份類型獲取一組??List?asList();?//轉(zhuǎn)換為L(zhǎng)ist??Set?asSet();?//轉(zhuǎn)換為Set??Collection?fromRealm(String?realmName);?//根據(jù)Realm名字獲取??Set<String>?getRealmNames();?//獲取所有身份驗(yàn)證通過的Realm名字??boolean?isEmpty();?//判斷是否為空?? }??? 復(fù)制代碼

    因?yàn)镻rincipalCollection聚合了多個(gè),此處最需要注意的是getPrimaryPrincipal,如果只有一個(gè)Principal那么直接返回即可,如果有多個(gè)Principal,則返回第一個(gè)(因?yàn)閮?nèi)部使用Map存儲(chǔ),所以可以認(rèn)為是返回任意一個(gè));oneByType / byType根據(jù)憑據(jù)的類型返回相應(yīng)的Principal;fromRealm根據(jù)Realm名字(每個(gè)Principal都與一個(gè)Realm關(guān)聯(lián))獲取相應(yīng)的Principal。

    AuthorizationInfo

    AuthorizationInfo用于聚合授權(quán)信息的:

    public?interface?AuthorizationInfo?extends?Serializable?{??Collection<String>?getRoles();?//獲取角色字符串信息??Collection<String>?getStringPermissions();?//獲取權(quán)限字符串信息??Collection<Permission>?getObjectPermissions();?//獲取Permission對(duì)象信息?? }??? 復(fù)制代碼

    當(dāng)我們使用AuthorizingRealm時(shí),如果身份驗(yàn)證成功,在進(jìn)行授權(quán)時(shí)就通過doGetAuthorizationInfo方法獲取角色/權(quán)限信息用于授權(quán)驗(yàn)證。 Shiro提供了一個(gè)實(shí)現(xiàn)SimpleAuthorizationInfo,大多數(shù)時(shí)候使用這個(gè)即可。


    我們?cè)俑櫼幌麓a,看看是如何調(diào)用Authorizer

    subject.hasRole("admin") 復(fù)制代碼
  • 調(diào)用DelegatingSubject類的hasRole方法
  • public boolean hasRole(String roleIdentifier) {return hasPrincipals() && securityManager.hasRole(getPrincipals(), roleIdentifier);} 復(fù)制代碼
  • 調(diào)用AuthorizingSecurityManager的hasRole
  • public boolean hasRole(PrincipalCollection principals, String roleIdentifier) {return this.authorizer.hasRole(principals, roleIdentifier);} 復(fù)制代碼
  • AuthorizingSecurityManager類在創(chuàng)建的時(shí)候就注入了ModularRealmAuthorizer類為authorizer
  • public AuthorizingSecurityManager() {super();this.authorizer = new ModularRealmAuthorizer();} 復(fù)制代碼
  • 繼續(xù)跟進(jìn)到ModularRealmAuthorizer的hasRole方法
  • public boolean hasRole(PrincipalCollection principals, String roleIdentifier) {assertRealmsConfigured();for (Realm realm : getRealms()) {if (!(realm instanceof Authorizer)) continue;if (((Authorizer) realm).hasRole(principals, roleIdentifier)) {return true;}}return false;} 復(fù)制代碼
  • 此處的hasRole是調(diào)用AuthorizingRealm抽象類的hasRole方法。同理,isPermitted也是最后調(diào)用到此。
  • public boolean hasRole(PrincipalCollection principal, String roleIdentifier) {AuthorizationInfo info = getAuthorizationInfo(principal);return hasRole(roleIdentifier, info);}protected boolean hasRole(String roleIdentifier, AuthorizationInfo info) {return info != null && info.getRoles() != null && info.getRoles().contains(roleIdentifier);}public boolean isPermitted(PrincipalCollection principals, String permission) {Permission p = getPermissionResolver().resolvePermission(permission);return isPermitted(principals, p);}public boolean isPermitted(PrincipalCollection principals, Permission permission) {AuthorizationInfo info = getAuthorizationInfo(principals);return isPermitted(permission, info);}//changed visibility from private to protected for SHIRO-332protected boolean isPermitted(Permission permission, AuthorizationInfo info) {Collection<Permission> perms = getPermissions(info);if (perms != null && !perms.isEmpty()) {for (Permission perm : perms) {if (perm.implies(permission)) {return true;}}}return false;} 復(fù)制代碼

    總結(jié)

    以上是生活随笔為你收集整理的SpringBoot+Shiro学习(四):Realm授权的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。