Shiro1.x中SecurityManager是如何使用CacheManager的

浏览:1022 发布日期:2024-04-14 11:16:55

根据Shiro 1.x的文档,SessionManager可以手动设置CacheManager,也可以配置一个`CacheManager`的bean,那么它是如何感知`CacheManager`的bean的呢。


我们首先看下SecurityManager接口继承结构:


SecurityManager-uml图.png


CacheManagerAware接口

public interface CacheManagerAware {
    void setCacheManager(CacheManager var1);
}

如果一个类实现了这个接口,那么将会调用setCacheManager来应用它。

SecurityManager接口

它继承了AuthenticatorAuthorizer  SessionManager 接口,主要提供了loginlogoutcreateSubject方法。这里没有涉及CacheManager接口。

CachingSecurityManager类

public interface SecurityManager extends Authenticator, Authorizer, SessionManager
{
    /**
     * The CacheManager to use to perform caching operations to enhance performance.  Can be null.
     */
    private CacheManager cacheManager;
    ...

    public CacheManager getCacheManager() {
        return cacheManager;
    }

       public void setCacheManager(CacheManager cacheManager) {
        this.cacheManager = cacheManager;
        afterCacheManagerSet();
    }

       protected void afterCacheManagerSet() {
        applyEventBusToCacheManager();
    }
    ...
}

它是一个抽象类,我们这里主要关注它实现了SecurityManagerCacheManagerAware接口。它包含一个CacheManger类型的字段,对于缓存的管理全部交给了子类。

RealmSecurityManager

public abstract class RealmSecurityManager extends CachingSecurityManager

它继承了CachingSecurityManager类,它维护一个Realm集合,如果Realm实现了CachingManagerAware接口,将设置它们的cacheManager

AuthenticatingSecurityManager

public abstract class AuthenticatingSecurityManager extends RealmSecurityManage

这个类没有涉及CacheManager,这里不讨论。

AuthorizingSecurityManager

public abstract class AuthorizingSecurityManager extends AuthenticatingSecurityManager

这个类没有涉及CacheManager,这里不讨论。

SessionsSecurityManager

public abstract class SessionsSecurityManager extends AuthorizingSecurityManager {

   private SessionManager sessionManager;

   ...
}

这个类处理session操作,它持有一个Sessionmanager对象,将涉及session的操作,委托给它。

如果SessionManager实现了CacheMangerAware接口,它会设置CacheManager

protected void applyCacheManagerToSessionManager() {
    if (this.sessionManager instanceof CacheManagerAware) {
        ((CacheManagerAware) this.sessionManager).setCacheManager(getCacheManager());
    }
}

DefaultSecurityManager

public class DefaultSecurityManager extends SessionsSecurityManager

没有涉及CacheManager的内容。

DefaultWebSecurityManager

public class DefaultWebSecurityManager extends DefaultSecurityManager implements WebSecurityManager

没有涉及CacheManager的内容。

======================================= spring自动配置

先看类图:

AbstractShiroConfiguration-uml图.png


AbstractShiroConfiguration

public class AbstractShiroConfiguration {

    @Autowired(required = false)
    protected CacheManager cacheManager;

这个配置类,尝试注入CacheManager

它通过securitymanager方法,配置默认的SessionsSecurityManager:

protected SessionsSecurityManager createSecurityManager() {
    DefaultSecurityManager securityManager = new DefaultSecurityManager();
    securityManager.setSubjectDAO(subjectDAO());
    securityManager.setSubjectFactory(subjectFactory());

    RememberMeManager rememberMeManager = rememberMeManager();
    if (rememberMeManager != null) {
        securityManager.setRememberMeManager(rememberMeManager);
    }

    return securityManager;
}

protected SessionsSecurityManager securityManager(List<Realm> realms) {
    SessionsSecurityManager securityManager = createSecurityManager();
    securityManager.setAuthenticator(authenticator());
    securityManager.setAuthorizer(authorizer());
    securityManager.setRealms(realms);
    securityManager.setSessionManager(sessionManager());
    securityManager.setEventBus(eventBus);

    if (cacheManager != null) {
        securityManager.setCacheManager(cacheManager);
    }

    return securityManager;
}

ShiroAutoConfiguration

@Configuration
@SuppressWarnings("SpringFacetCodeInspection")
@ConditionalOnProperty(name = "shiro.enabled", matchIfMissing = true)
public class ShiroAutoConfiguration extends AbstractShiroConfiguration

这里我们关心的只是securityManager(List<Realm> realms)方法:

@Bean
@ConditionalOnMissingBean
@Override
protected SessionsSecurityManager securityManager(List<Realm> realms) {
    return super.securityManager(realms);
}

它只是调用AbstractShiroConfiguration#securityManager方法。

ShiroWebAutoConfiguration 自动配置类

@Configuration
@AutoConfigureBefore(ShiroAutoConfiguration.class)
@AutoConfigureAfter(ShiroWebMvcAutoConfiguration.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnProperty(name = "shiro.web.enabled", matchIfMissing = true)
public class ShiroWebAutoConfiguration extends AbstractShiroWebConfiguration

这里我们关心的只是securityManager(List<Realm> realms)方法,仅是调用父类的方法而已:

@Bean
@ConditionalOnMissingBean
@Override
protected SessionsSecurityManager securityManager(List<Realm> realms) {
    return super.securityManager(realms);
}

ShiroWebAutoConfiguration

@Configuration
@AutoConfigureBefore(ShiroAutoConfiguration.class)
@AutoConfigureAfter(ShiroWebMvcAutoConfiguration.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnProperty(name = "shiro.web.enabled", matchIfMissing = true)
public class ShiroWebAutoConfiguration extends AbstractShiroWebConfiguration

这里我们关心的只是securityManager(List<Realm> realms)方法,仅是调用父类的方法而已:

@Bean
@ConditionalOnMissingBean
@Override
protected SessionsSecurityManager securityManager(List<Realm> realms) {
    return super.securityManager(realms);
}

ShiroConfiguration、ShiroWebConfiguration

这个是用于普通的Spring程序的配置类。