Shiro使用和源码分析---4

DefaultWebSecurityManager源码分析

在上一篇的分析中使用了三个有关Subject的函数,getSubject、login、isAuthenticated,这里就来分析它们的源码。
本章首先开始研究shiro框架的SecurityManager,这里以web项目为例,分析DefaultWebSecurityManager。为了方便后面的分析,这里首先看一下Spring中的配置,

    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="testRealm"/>
    </bean>
    <bean id="testRealm" class="org.apache.shiro.realm.AuthorizingRealm">
    </bean>

下面先看一下DefaultWebSecurityManager的父类和接口。

public class DefaultWebSecurityManager extends DefaultSecurityManager implements WebSecurityManager
public class DefaultSecurityManager extends SessionsSecurityManager
public abstract class SessionsSecurityManager extends AuthorizingSecurityManager
public abstract class AuthorizingSecurityManager extends AuthenticatingSecurityManager
public abstract class AuthenticatingSecurityManager extends RealmSecurityManager
public abstract class RealmSecurityManager extends CachingSecurityManager
public abstract class CachingSecurityManager implements SecurityManager, Destroyable, CacheManagerAware

这里,简单从字面意思上看,CachingSecurityManager和缓存有关,RealmSecurityManager和Realm有关,Realm简单理解就是和数据存储有关的一个东东,AuthenticatingSecurityManager和验证有关,AuthorizingSecurityManager和授权有关,SessionsSecurityManager就是和Session有关啦,后面都会分析道。

DefaultWebSecurityManager构造函数

DefaultWebSecurityManager的构造函数会层层调用到最上层的构造函数,因此,本文从最后的构造函数开始分析,CachingSecurityManager的构造函数为空函数,RealmSecurityManager的构造函数也是空函数,再看AuthenticatingSecurityManager的构造函数,代码如下

    public AuthenticatingSecurityManager() {
        super();
        this.authenticator = new ModularRealmAuthenticator();
    }

ModularRealmAuthenticator和验证有关,其构造函数如下

    public ModularRealmAuthenticator() {
        this.authenticationStrategy = new AtLeastOneSuccessfulStrategy();
    }

AtLeastOneSuccessfulStrategy就是一些验证的规则,其构造函数为空函数。再看AuthorizingSecurityManager的构造函数,

    public AuthorizingSecurityManager() {
        super();
        this.authorizer = new ModularRealmAuthorizer();
    }

ModularRealmAuthorizer的构造函数也为空函数。再看SessionsSecurityManager的构造函数,

    public SessionsSecurityManager() {
        super();
        this.sessionManager = new DefaultSessionManager();
        applyCacheManagerToSessionManager();
    }

applyCacheManagerToSessionManager就是进一步设置DefaultSessionManager,不往下看了。
DefaultSessionManager的构造函数如下

    public DefaultSessionManager() {
        this.deleteInvalidSessions = true;
        this.sessionFactory = new SimpleSessionFactory();
        this.sessionDAO = new MemorySessionDAO();
    }

SimpleSessionFactory的构造函数为空函数。MemorySessionDAO的构造函数如下

    public MemorySessionDAO() {
        this.sessions = new ConcurrentHashMap<Serializable, Session>();
    }

DefaultSecurityManager的构造函数如下

    public DefaultSecurityManager() {
        super();
        this.subjectFactory = new DefaultSubjectFactory();
        this.subjectDAO = new DefaultSubjectDAO();
    }

DefaultSubjectFactory用来构造Subject,其构造函数为空函数。DefaultSubjectDAO的构造函数如下

    public DefaultSubjectDAO() {
        this.sessionStorageEvaluator = new DefaultSessionStorageEvaluator();
    }

DefaultSessionStorageEvaluator的构造函数也为空函数。
最后看DefaultWebSecurityManager的构造函数,代码如下

    public DefaultWebSecurityManager(Collection<Realm> realms) {
        this();
        setRealms(realms);
    }

这是其中一个DefaultWebSecurityManager的构造函数,this为无参的构造函数,代码如下

    public DefaultWebSecurityManager() {
        super();
        ((DefaultSubjectDAO) this.subjectDAO).setSessionStorageEvaluator(new DefaultWebSessionStorageEvaluator());
        this.sessionMode = HTTP_SESSION_MODE;
        setSubjectFactory(new DefaultWebSubjectFactory());
        setRememberMeManager(new CookieRememberMeManager());
        setSessionManager(new ServletContainerSessionManager());
    }

subjectDAO为前面构造的DefaultSubjectDAO,其setSessionStorageEvaluator函数只是简单的赋值。DefaultWebSessionStorageEvaluator的构造函数为空函数。
DefaultWebSubjectFactory的构造函数为空函数,不去管它,setSubjectFactory也是简单的赋值。
CookieRememberMeManager的构造函数如下

    public CookieRememberMeManager() {
        Cookie cookie = new SimpleCookie(DEFAULT_REMEMBER_ME_COOKIE_NAME);
        cookie.setHttpOnly(true);
        cookie.setMaxAge(Cookie.ONE_YEAR);
        this.cookie = cookie;
    }

这里构造了一个名称为rememberMe的SimpleCookie,其构造函数很简单,不去看它。然后设置该Cookie只支持http的连接,并且设置该Cookie的有效期为一年。setRememberMeManager也为简单的赋值,不去管它。ServletContainerSessionManager的构造函数为空函数,setSessionManager也基本上是直接赋值(里面调用了一些Cache相关的管理类),这里不管它。

setRealms

回头再看DefaultWebSecurityManager的构造函数,setRealms定义在RealmSecurityManager中,代码如下

    public void setRealms(Collection<Realm> realms) {
        if (realms == null) {
            throw new IllegalArgumentException("Realms collection argument cannot be null.");
        }
        if (realms.isEmpty()) {
            throw new IllegalArgumentException("Realms collection argument cannot be empty.");
        }
        this.realms = realms;
        afterRealmsSet();
    }

这里就是简单的赋值,然后调用afterRealmsSet函数,定义在AuthorizingSecurityManager中,

    protected void afterRealmsSet() {
        super.afterRealmsSet();
        if (this.authorizer instanceof ModularRealmAuthorizer) {
            ((ModularRealmAuthorizer) this.authorizer).setRealms(getRealms());
        }
    }

这里的authorizer确实是类ModularRealmAuthorizer的实例(看前面AuthorizingSecurityManager的构造函数),因此将realms设置进去,setRealms只是简单的赋值,不往下看了。
AuthorizingSecurityManager继承自AuthenticatingSecurityManager,因此接着看AuthenticatingSecurityManager的afterRealmsSet函数,

    protected void afterRealmsSet() {
        super.afterRealmsSet();
        if (this.authenticator instanceof ModularRealmAuthenticator) {
            ((ModularRealmAuthenticator) this.authenticator).setRealms(getRealms());
        }
    }

这里的authenticator 确实实例化了ModularRealmAuthenticator,因此类似,设置realms。AuthenticatingSecurityManager继承自RealmSecurityManager,因此继续看RealmSecurityManager的afterRealmsSet函数,

    protected void afterRealmsSet() {
        applyCacheManagerToRealms();
    }
    protected void applyCacheManagerToRealms() {
        CacheManager cacheManager = getCacheManager();
        Collection<Realm> realms = getRealms();
        if (cacheManager != null && realms != null && !realms.isEmpty()) {
            for (Realm realm : realms) {
                if (realm instanceof CacheManagerAware) {
                    ((CacheManagerAware) realm).setCacheManager(cacheManager);
                }
            }
        }
    }

getCacheManager这里返回null,所以这里就不会往下继续执行了。
总结一下,本章主要介绍了DefaultWebSecurityManager的构造函数,以及它父类的一些构造函数,简而言之,都是一些基本的实例化然后赋值。另外DefaultWebSecurityManager构造函数中还会设置Realms,和数据存取有关。后面的分析中,都会逐渐用到这些类以及变量,这里有个大概的印象就行了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值