吃透Shiro源码6----AuthorizingRealm

技术手法

(1)AuthorizingRealm设计思路

AuthorizingRealm这个类的大致设计思路与AuthenticationRealm一致。暂时学到的最核心的方法就是通过 凭证对象PrincipalCollection对象获取缓存中的AuthorizationInfo对象。其核心思想就是如何缓存。此方法暂时没有判断角色与权限对应关系,这个以后再说。

public AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {

        LOGGER.debug("使用PrincipalCollection来获取AuthorizationInfo");
        if (principals == null) {
            return null;
        }

        AuthorizationInfo info = null;
		//获取可用的缓存,详见下面
        Cache<Object, AuthorizationInfo> cache = getAvailableAuthorizationCache();
        if (cache != null) {
            //此方法就是返回principals本身
            Object key = getAuthorizationCacheKey(principals);
            //取值,Shiro默认可以认为key为null
            info = cache.get(key);
            if (info == null) {
                LOGGER.debug("缓存中没取到AuthenticationInfo信息");
            } else {
                LOGGER.debug("从缓存中取出AuthorizationInfo");
            }
        }

        if (info == null) {
            //由用户重写
            info = doGetAuthorizationInfo();
            if (cache != null && info != null) {
                //就是principals这个家伙
                Object key = getAuthorizationCacheKey(principals);
                LOGGER.debug("将principal与AuthorizationInfo进行缓存");
                //key可以为空
                cache.put(key, info);
            }
        }

        return info;
    }

核心步骤(1):getAvailableAuthorizationCache(PrincipalCollection)。先尝试拿到内部缓存对象。如果没有内部缓存,则查看缓存是否开启,并使用懒加载。使用CacheManager对象创建一个Cache并将其赋值给this.authorizationCache。

 /**
     * 核心,获取可用的内部的授权缓存
     *
     * @return 授权缓存Cache对象
     */
    private Cache<Object, AuthorizationInfo> getAvailableAuthorizationCache() {

        Cache<Object, AuthorizationInfo> cache = this.authorizationCache;
        if (cache == null && isAuthorizationCachingEnable()) {
            //懒加载,创建缓存
            cache = getAuthorizationCacheLazy();
        }
        return cache;

    }
private Cache<Object, AuthorizationInfo> getAuthorizationCacheLazy() {

        Cache<Object, AuthorizationInfo> cache = this.authorizationCache;
        if (cache == null && isAuthorizationCachingEnable()) {
            CacheManager cacheManager = super.getCacheManager();
            if (cacheManager != null) {
                String cacheName = getAuthorizationCacheName();
                LOGGER.debug("使用CacheManager创建名字为{}的授权缓存", cacheName);
                this.authorizationCache = cacheManager.getCache(cacheName);
            }else{
                LOGGER.debug("暂未设置CacheManager,因此获取不到授权缓存");
            }
        } 
        return this.authorizationCache;
    }

重点研究类

import com.wise.security.authc.AuthenticationInfo;
import com.wise.security.authc.AuthenticationToken;
import com.wise.security.authc.credential.CredentialsMatcher;
import com.wise.security.authz.AuthorizationInfo;
import com.wise.security.authz.permission.*;
import com.wise.security.cache.Cache;
import com.wise.security.cache.CacheManager;
import com.wise.security.subject.PrincipalCollection;
import com.wise.security.util.Initializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicInteger;

public class AuthorizingRealm extends AuthenticatingRealm
        implements Initializable, PermissionResolverAware, RolePermissionResolverAware {

    private static final Logger LOGGER = LoggerFactory.getLogger(AuthorizingRealm.class);
    private static final AtomicInteger INSTACE_COUNT = new AtomicInteger();
    private static final String DEFAULT_AUTHOR_CACHE_SUFFIX = ".authorizationCache";

    private boolean authorizationCachingEnabled;
    private Cache<Object, AuthorizationInfo> authorizationCache;
    private String authorizationCacheName;

    /**
     * 能把权限字符串解析成权限对象
     */
    private PermissionResolver permissionResolver;

    /**
     * 把角色字符串解析成权限对象列表
     */
    private RolePermissionResolver rolePermissionResolver;

    //------------------------------------构造函数  Start-------------------------------------------

    public AuthorizingRealm() {
        this(null, null);
    }

    public AuthorizingRealm(CacheManager cacheManager) {
        this(cacheManager, null);
    }

    public AuthorizingRealm(CredentialsMatcher credentialsMatcher) {
        this(null, credentialsMatcher);
    }

    public AuthorizingRealm(CacheManager cacheManager, CredentialsMatcher credentialsMatcher) {
        //new SimpleCredentialsMatcher()
        super();
        if (cacheManager != null) {
            setCacheManager(cacheManager);
        }
        if (credentialsMatcher != null) {
            setCredentialsMatcher(credentialsMatcher);
        }
        this.authorizationCachingEnabled = true;

        //默认提供了一个PermissionResolver
        this.permissionResolver = new WildcardPermissionResolver();

        int instanceNumber = INSTACE_COUNT.getAndIncrement();
        //包名+类名 +
        this.authorizationCacheName = getClass().getName() + DEFAULT_AUTHOR_CACHE_SUFFIX;
        if (instanceNumber > 0) {
            // com.jay.AuthorizingRealm.authorizationCache.15
            this.authorizationCacheName = this.authorizationCacheName + "." + instanceNumber;
        }
    }

    //------------------------------------构造函数  End-------------------------------------------

    //------------------------------------get And set  Start-------------------------------------------


    @Override
    public void setName(String name) {
        super.setName(name);
        //覆盖默认的构造函数处理出来的名字。
        if (this.authorizationCacheName != null && this.authorizationCacheName.startsWith(getClass().getName())) {
            this.authorizationCacheName = name + DEFAULT_AUTHOR_CACHE_SUFFIX;
        }
    }

    public boolean isAuthorizationCachingEnable() {
        //CachingRealm需要开启缓存
        return authorizationCachingEnabled && super.isCachingEnabled();
    }

    public void setAuthorizationCachingEnable(boolean authorizationCachingEnabled) {
        this.authorizationCachingEnabled = authorizationCachingEnabled;
    }

    public Cache<Object, AuthorizationInfo> getAuthorizationCache() {
        return authorizationCache;
    }

    public void setAuthorizationCache(Cache<Object, AuthorizationInfo> authorizationCache) {
        this.authorizationCache = authorizationCache;
    }

    public String getAuthorizationCacheName() {
        return authorizationCacheName;
    }

    public void setAuthorizationCacheName(String authorizationCacheName) {
        this.authorizationCacheName = authorizationCacheName;
    }

    public PermissionResolver getPermissionResolver() {
        return permissionResolver;
    }

    public RolePermissionResolver getRolePermissionResolver() {
        return rolePermissionResolver;
    }

    @Override
    public void setRolePermissionResolver(RolePermissionResolver rolePermissionResolver) {
        this.rolePermissionResolver = rolePermissionResolver;
    }

    @Override
    public void setPermissionResolver(PermissionResolver permissionResolver) {
        this.permissionResolver = permissionResolver;
    }

    //------------------------------------get And set  End-------------------------------------------

    @Override
    protected void onInit() {
        super.onInit();
        //创建这么多次缓存干啥?确保内部缓存初始化
        getAvailableAuthorizationCache();
    }

    @Override
    protected void afterCacheManagerSet() {
        super.afterCacheManagerSet();
        //创建这么多次缓存干啥?确保内部缓存初始化
        getAvailableAuthorizationCache();
    }

    /**
     * 核心:使用PrincipalCollection来获取权限Info对象
     * 如果缓存有,则返回
     * 如果缓存没有,则让用户实现
     *
     * @param principals
     * @return
     */
    public AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {

        LOGGER.debug("使用PrincipalCollection来获取AuthorizationInfo");
        if (principals == null) {
            return null;
        }

        AuthorizationInfo info = null;

        Cache<Object, AuthorizationInfo> cache = getAvailableAuthorizationCache();
        if (cache != null) {
            Object key = getAuthorizationCacheKey(principals);
            info = cache.get(key);
            if (info == null) {
                LOGGER.debug("缓存中没取到AuthenticationInfo信息");
            } else {
                LOGGER.debug("从缓存中取出AuthorizationInfo");
            }
        }

        if (info == null) {
            //由用户重写
            info = doGetAuthorizationInfo();
            if (cache != null && info != null) {
                //就是principals这个家伙
                Object key = getAuthorizationCacheKey(principals);
                LOGGER.debug("将principal与AuthorizationInfo进行缓存");
                cache.put(key, info);
            }
        }

        return info;
    }

    protected void clearCachedAuthorizationInfo(PrincipalCollection principals) {

        if (principals == null) {
            return;

            Cache<Object, AuthorizationInfo> cache = getAvailableAuthorizationCache();

            if (cache != null) {
                Object key = getAuthorizationCacheKey(principals);
                cache.remove(key);
            }
        }


        /**
         * 获取授权缓存的Key
         * 授权缓存存放形势为:Principal -- AuthorizationInfo
         *
         * @param principals
         * @return
         */

    protected Object getAuthorizationCacheKey(PrincipalCollection principals) {
        return principals;
    }

    /**
     * 核心,获取可用的内部的授权缓存
     *
     * @return 授权缓存Cache对象
     */
    private Cache<Object, AuthorizationInfo> getAvailableAuthorizationCache() {

        Cache<Object, AuthorizationInfo> cache = this.authorizationCache;
        if (cache == null && isAuthorizationCachingEnable()) {
            //懒加载,创建缓存
            cache = getAuthorizationCacheLazy();
        }
        return cache;

    }

    private Cache<Object, AuthorizationInfo> getAuthorizationCacheLazy() {

        Cache<Object, AuthorizationInfo> cache = this.authorizationCache;
        if (cache == null && isAuthorizationCachingEnable()) {
            CacheManager cacheManager = super.getCacheManager();
            if (cacheManager != null) {
                String cacheName = getAuthorizationCacheName();
                LOGGER.debug("使用CacheManager创建名字为{}的授权缓存", cacheName);
                this.authorizationCache = cacheManager.getCache(cacheName);
            }else{
                LOGGER.debug("暂未设置CacheManager,因此获取不到授权缓存");
            }
        } 
        return this.authorizationCache;
    }


    @Override
    protected abstract AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) ;

    private abstract  AuthorizationInfo doGetAuthorizationInfo() ;
}

发布了315 篇原创文章 · 获赞 243 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/yanluandai1985/article/details/103669018
今日推荐