首页 > 代码库 > 基于debug 来看 shiro 如何 解析role 的权限

基于debug 来看 shiro 如何 解析role 的权限

我们接着上个文章说。

我们还是基于上次说的那个例子。地址为:

https://github.com/fengyapeng/shiro-example/tree/master/shiro-example-chapter3

上个文章,我们了解了,针对用户,shiro如何是解析权限的,这个文章说一说角色。好吧,我认为,这个角色有点儿坑。

根据debug 来的源代码,

我们只能判断某一个用户是不是有某一个角色,

至于角色的权限,实际上有已经解析好了都。

我先来截图,说明一下基于配置文件中的的Realm 。


,好的。我们继续。

其中最关键的部分为:SimpleAccountRealm 这一部分。

我们先看这一段代码:

org.apache.shiro.authz.ModularRealmAuthorizer

    /**
     * Returns <code>true</code> if any of the configured realms'
     * {@link #isPermitted(org.apache.shiro.subject.PrincipalCollection, String)} returns <code>true</code>,
     * <code>false</code> otherwise.
     */
    public boolean isPermitted(PrincipalCollection principals, String permission) {
        assertRealmsConfigured();
        for (Realm realm : getRealms()) {
            if (!(realm instanceof Authorizer)) continue;
            if (((Authorizer) realm).isPermitted(principals, permission)) {
                return true;
            }
        }
        return false;
    }

这一段代码熟悉,上节中,我们就提到了这个类的这个方法。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

org.apache.shiro.realm.AuthorizingRealm extends AuthenticatingRealm
        implements Authorizer, Initializable, PermissionResolverAware, RolePermissionResolverAware
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. public boolean isPermitted(PrincipalCollection principals, Permission permission) {  
  2.     AuthorizationInfo info = getAuthorizationInfo(principals);  
  3.     return isPermitted(permission, info);  
  4. }  
以上代码为:Realm 拿到 AuthorizationInfo ,通过 Permission,AuthorizationInfo 权限认定
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

引自上篇文章中的一段,

AuthorizationInfo info = getAuthorizationInfo(principals); info中已经包含了user 的role 和 操作。 

这个函数调用的方法为:

org.apache.shiro.realm.AuthorizingRealm extends AuthenticatingRealm
        implements Authorizer, Initializable, PermissionResolverAware, RolePermissionResolverAware

protected AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {

        if (principals == null) {
            return null;
        }

        AuthorizationInfo info = null;

        if (log.isTraceEnabled()) {
            log.trace("Retrieving AuthorizationInfo for principals [" + principals + "]");
        }

        Cache<Object, AuthorizationInfo> cache = getAvailableAuthorizationCache();
        if (cache != null) {
            if (log.isTraceEnabled()) {
                log.trace("Attempting to retrieve the AuthorizationInfo from cache.");
            }
            Object key = getAuthorizationCacheKey(principals);
            info = cache.get(key);
            if (log.isTraceEnabled()) {
                if (info == null) {
                    log.trace("No AuthorizationInfo found in cache for principals [" + principals + "]");
                } else {
                    log.trace("AuthorizationInfo found in cache for principals [" + principals + "]");
                }
            }
        }


        if (info == null) {
            // Call template method if the info was not found in a cache
            info = doGetAuthorizationInfo(principals);
            // If the info is not null and the cache has been created, then cache the authorization info.
            if (info != null && cache != null) {
                if (log.isTraceEnabled()) {
                    log.trace("Caching authorization info for principals: [" + principals + "].");
                }
                Object key = getAuthorizationCacheKey(principals);
                cache.put(key, info);
            }
        }

        return info;
    }
其中,doGetAuthorizationInfo(principals);才是真正的 拿到info 对象。

org.apache.shiro.realm.SimpleAccountRealm extends AuthorizingRealm

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = getUsername(principals);
        USERS_LOCK.readLock().lock();
        try {
            return this.users.get(username);
        } finally {
            USERS_LOCK.readLock().unlock();
        }
    }


this.users.get(username)后面的代码,我就不贴了。users中就是username,AuthorizationInfo  的映射。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

org.apache.shiro.realm.AuthorizingRealm extends AuthenticatingRealm
        implements Authorizer, Initializable, PermissionResolverAware, RolePermissionResolverAware

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1.  private boolean isPermitted(Permission permission, AuthorizationInfo info) {  
  2.         Collection<Permission> perms = getPermissions(info);  
  3.         if (perms != null && !perms.isEmpty()) {  
  4.             for (Permission perm : perms) {  
  5.                 if (perm.implies(permission)) {  
  6.                     return true;  
  7.                 }  
  8.             }  
  9.         }  
  10.         return false;  
  11.     }
以上代码为: Permission调用implies ,通过自定义实现的Permission,判定权限

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

以上代码是上篇文章中提到的。

其中getPermissions(info) 是通过info 拿到 Permission 的集合。跳进去看看是怎么一回事。

org.apache.shiro.realm.AuthorizingRealm extends AuthenticatingRealm
        implements Authorizer, Initializable, PermissionResolverAware, RolePermissionResolverAware

 private Collection<Permission> getPermissions(AuthorizationInfo info) {
        Set<Permission> permissions = new HashSet<Permission>();

        if (info != null) {
            Collection<Permission> perms = info.getObjectPermissions();
            if (!CollectionUtils.isEmpty(perms)) {
                permissions.addAll(perms);
            }
            perms = resolvePermissions(info.getStringPermissions());
            if (!CollectionUtils.isEmpty(perms)) {
                permissions.addAll(perms);
            }

            perms =<span style="color:#ff0000;"> resolveRolePermissions(info.getRoles());</span>
            if (!CollectionUtils.isEmpty(perms)) {
                permissions.addAll(perms);
            }
        }

        if (permissions.isEmpty()) {
            return Collections.emptySet();
        } else {
            return Collections.unmodifiableSet(permissions);
        }
    }

 private Collection<Permission> resolveRolePermissions(Collection<String> roleNames) {
        Collection<Permission> perms = Collections.emptySet();
        RolePermissionResolver resolver = getRolePermissionResolver();
        if (resolver != null && !CollectionUtils.isEmpty(roleNames)) {
            perms = new LinkedHashSet<Permission>(roleNames.size());
            for (String roleName : roleNames) {
                Collection<Permission> resolved = resolver.resolvePermissionsInRole(roleName);
                if (!CollectionUtils.isEmpty(resolved)) {
                    perms.addAll(resolved);
                }
            }
        }
        return perms;
    }
我能说,
RolePermissionResolver resolver = getRolePermissionResolver();拿到的值是null 么?
我把info 中的值给截图看看。
<img src=http://www.mamicode.com/"http://img.blog.csdn.net/20141205185700968?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZzI3MTU2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />>


好吧。其他的我都不说了,其实都是Realm 中定义的东西。

另外,我再贴一个url:http://jinnianshilongnian.iteye.com/blog/2020017,这个讲的不错。在此学习的。


基于debug 来看 shiro 如何 解析role 的权限