吃透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() ;
}