php中引入shiro,shiro源码篇 - shiro的session管理,你值得拥有

前言

开心一刻

开学了,表弟和同学因为打架,老师让他回去叫家长。表弟硬气的说:不用,我打得过他。老师板着脸对他说:和你打架的那位同学已经回去叫家长了。表弟犹豫了一会依然硬气的说:可以,两个我也打得过。老师:......

路漫漫其修远兮,吾将上下而求索!

前情回顾

大家还记得

HttpServletRequestWrapper是HttpServletRequest的装饰类,我们通过继承HttpServletRequestWrapper来实现我们自定义的HttpServletRequest:CustomizeSessionHttpServletRequest,重写CustomizeSessionHttpServletRequest的getSession,将其指向我们自定义的session。然后通过Filter将CustomizeSessionHttpServletRequest添加到Filter chain中,使得到达Servlet的ServletRequest是我们的CustomizeSessionHttpServletRequest。

今天不讲session共享,我们先来看看shiro的session管理

SecurityManager

SecurityManager,安全管理器;即所有与安全相关的操作都会与SecurityManager交互;它管理着所有Subject,所有Subject都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager;SecurityManager是shiro的核心,它负责与shiro的其他组件进行交互,类似SpringMVC中的DispatcherServlet或Struts2中的FilterDispatcher。

我们在使用shiro的时候,首先都会先初始化SecurityManager,然后往SecurityManager中注入shiro的其他组件,像sessionManager、realm等。我们的spring-boot-shiro中初始化的是DefaultWebSecurityManager,如下

11199

11199

@BeanpublicSecurityManager securityManager(AuthorizingRealm myShiroRealm, CacheManager shiroRedisCacheManager) {

DefaultWebSecurityManager securityManager= newDefaultWebSecurityManager();

securityManager.setCacheManager(shiroRedisCacheManager);

securityManager.setRememberMeManager(cookieRememberMeManager());

securityManager.setRealm(myShiroRealm);returnsecurityManager;

}View Code

SecurityManager类图

结构如下,认真看看,注意看下属性

11199

顶层组件SecurityManager直接继承了SessionManager且提供了SessionsSecurityManager实现,SessionsSecurityManager直接把会话管理委托给相应的SessionManager;SecurityManager的默认实现:DefaultSecurityManager及DefaultWebSecurityManager都继承了SessionsSecurityManager,也就是说:默认情况下,session的管理由DefaultSecurityManager或DefaultWebSecurityManager中的SessionManager来负责。

DefaultSecurityManager

默认安全管理器,用于我们的javaSE安全管理,一般而言用到的少,但我们需要记住,万一哪次有这个需求呢。

我们来看下他的构造方法

11199

默认的sessionManager是DefaultSessionManager,DefaultSessionManager具体详情请看下文。

DefaultWebSecurityManager

默认web安全管理器,用于我们的web安全管理;一般而言,我们的应用中初始化此安全管理器。

我们来看看其构造方法

11199

11199

11199

publicDefaultWebSecurityManager() {super(); //会调用SessionsSecurityManager的构造方法,实例化DefaultSessionManager

((DefaultSubjectDAO) this.subjectDAO).setSessionStorageEvaluator(newDefaultWebSessionStorageEvaluator());this.sessionMode =HTTP_SESSION_MODE;

setSubjectFactory(newDefaultWebSubjectFactory());

setRememberMeManager(newCookieRememberMeManager());

setSessionManager(new ServletContainerSessionManager()); //设置sessionManager,替换掉上面的DefaultSessionManager

}View Code

可以看出此时的sessionManager是ServletContainerSessionManager,ServletContainerSessionManager具体详情请看下文。

由此可知默认情况下,DefaultSecurityManager会将session管理委托给DefaultSessionManager,而DefaultWebSecurityManager则将session管理委托给ServletContainerSessionManager。

我们可以通过继承DefaultSecurityManager或DefaultWebSecurityManager来实现自定义SecurityManager,但一般而言没必要,DefaultSecurityManager和DefaultWebSecurityManager基本能满足我们的需要了,我们根据需求二选其一即可。无论DefaultSecurityManager还是DefaultWebSecurityManager,我们都可以通过setSessionManager方法来指定sessionManager,如果不指定sessionManager的话就用的SecurityManager默认的sessionManager。

SessionManager

shiro提供了完整的会话管理功能,不依赖底层容器,JavaSE应用和JavaEE应用都可以使用。会话管理器管理着应用中所有Subject的会话,包括会话的创建、维护、删除、失效、验证等工作。

SessionManager类图

11199

DefaultSessionManager

DefaultSecurityManager默认使用的SessionManager,用于JavaSE环境的session管理。

11199

通过上图可知(结合SecurityManager类图),session创建的关键入口是SessionsSecurityManager的start方法,此方法中会将session的创建任务委托给具体的SessionManager实现。

DefaultSessionManager继承自AbstractNativeSessionManager,没用重写start方法,所以此时AbstractNativeSessionManager的start方法会被调用,一路往下跟,最终会调用DefaultSessionManager的doCreateSession方法完成session的创建,doCreateSession方法大家可以自行去跟下,我在这总结一下:

创建session,并生成sessionId,session是shiro的SimpleSession类型,sessionId采用的是随机的UUID字符串;

sessionDAO类型是MemorySessionDAO,session存放在sessionDAO的private ConcurrentMap sessions;属性中,key是sessionId,value是session对象;

除了MemorySessionDAO,shiro还提供了EnterpriseCacheSessionDAO,具体两者有啥区别请看我的另一篇博客讲解。

ServletContainerSessionManager

DefaultWebSecurityManager默认使用的SessionManager,用于Web环境,直接使用的Servlet容器的会话,具体实现我们往下看。

ServletContainerSessionManager实现了SessionManager,并重写了SessionManager的start方法,那么我们从ServletContainerSessionManager的start方法开始来看看session的创建过程,如下图

11199

shiro有自己的HttpServletSession,HttpServletSession持有servlet的HttpSession的引用,最终对HttpServletSession的操作都会委托给HttpSession(

DefaultWebSessionManager

用于Web环境,可以替换ServletContainerSessionManager,废弃了Servlet容器的会话管理;通过此可以实现我们自己的session管理;

从SessionManager类图可知,DefaultWebSessionManager继承自DefaultSessionManager,也没有重写start方法,那么创建过程还是沿用的AbstractNativeSessionManager的start方法;如果我们没有指定自己的sessionDao,那么session还是存在MemorySessionDAO的ConcurrentMap sessions中,具体可以看上述中的DefaultSessionManager。

通过DefaultWebSessionManager实现session共享,尽请期待!

总结

两个类图

SecurityManager和SessionManager的类图需要认真看看;

Subject的所有交互都会委托给SecurityManager;SecurityManager是shiro的核心,它负责与shiro的其他组件进行交互,类似SpringMVC中的DispatcherServlet或Struts2中的FilterDispatcher;

SecurityManager会将session管理委托给SessionManager;SessionsSecurityManager的start方法中将session的创建委托给了具体的sessionManager,是创建session的关键入口。

shiro的SimpleSession与HttpServletSession

HttpServletSession只是servlet容器的session的装饰,最终还是依赖servlet容器,是shiro对servlet容器的session的一种支持;

而SimpleSession是shiro完完全全的自己实现,是shiro对session的一种拓展。

参考

《跟我学shiro》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值