细说shiro之六:session管理
我们先来看一下shiro中关于Session和Session Manager的类图。


如上图所示,shiro自己定义了一个新的Session接口,用于统一操作接口,并通过SessionManager实现Session管理。
其中的3个实现类HttpServletSession,SimpleSession和StoppingAwareProxiedSession是我们经常需要打交道的。
HttpServletSession
首先,我们来看看org.apache.shiro.web.session.HttpServletSession的实现。
public HttpServletSession(HttpSession httpSession, String host) {
if (httpSession == null) {
String msg = "HttpSession constructor argument cannot be null.";
throw new IllegalArgumentException(msg);
}
if (httpSession instanceof ShiroHttpSession) {
String msg = "HttpSession constructor argument cannot be an instance of ShiroHttpSession. This " +
"is enforced to prevent circular dependencies and infinite loops.";
throw new IllegalArgumentException(msg);
}
this.httpSession = httpSession;
if (StringUtils.hasText(host)) {
setHost(host);
}
}
显然,HttpServletSession只是简单对javax.servlet.http.HttpSession进行了封装,即:
在Web应用程序中,所有对Session相关的操作最终都是对javax.servlet.http.HttpSession进行的。

通过对上述Subject.login()的时序图分析可以知道:
在Web应用程序中,Shiro确实是通过ServletContainerSessionManager获取到容器创建的HttpSession再封装为HttpServletSession的。
也就是说,Subject.login()登录成功后用户的认证信息实际上是保存在HttpSession中的。如果此时Web应用程序部署了多实例,必须要进行Session同步。
我们知道,SecurityManager是整个Shiro框架的核心控制器,在SpringMVC中集成Shiro时,就需要明确配置对应的SecurityManager。
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- Single realm app. If you have multiple realms, use the 'realms' property instead. -->
<property name="realm" ref="myRealm" />
</bean>
而在org.apache.shiro.web.mgt.DefaultWebSecurityManager的实现中,使用的SessionManager就是ServletContainerSessionManager。
public DefaultWebSecurityManager() {
super();
((DefaultSubjectDAO) this.subjectDAO).setSessionStorageEvaluator(new DefaultWebSessionStorageEvaluator());
this.sessionMode = HTTP_SESSION_MODE;
setSubjectFactory(new DefaultWebSubjectFactory());
setRememberMeManager(new CookieRememberMeManager());
setSessionManager(new ServletContainerSessionManager()); // 配置Session Manager
}
SimpleSession
shiro具备完善的Session管理机制,当在命令行程序中使用Shiro框架时,同样可以执行与Web应用程序一样的Session操作。
此时,Shiro实际上使用SimpleSession实现。
StoppingAwareProxiedSession
实际上,StoppingAwareProxiedSession仅仅是一个Session包装类,即:
无论是HttpServletSession还是SimpleSession,在执行Subject.login()时保存到Subject中的Session都是StoppingAwareProxiedSession对象。
private class StoppingAwareProxiedSession extends ProxiedSession {
private final DelegatingSubject owner;
private StoppingAwareProxiedSession(Session target, DelegatingSubject owningSubject) {
super(target);
owner = owningSubject;
}
public void stop() throws InvalidSessionException {
super.stop();
owner.sessionStopped();
}
}
【参考】
https://shiro.apache.org/session-management.html
细说shiro之六:session管理的更多相关文章
- Shiro在Spring session管理
会话管理 在shiro里面可以发现所有的用户的会话信息都会由Shiro来进行控制,那么也就是说只要是与用户有关的一切的处理信息操作都可以通过Shiro取得,实际上可以取得的信息可以有用户名.主机名称等 ...
- Shiro权限管理框架(四):深入分析Shiro中的Session管理
其实关于Shiro的一些学习笔记很早就该写了,因为懒癌和拖延症晚期一直没有落实,直到今天公司的一个项目碰到了在集群环境的单点登录频繁掉线的问题,为了解决这个问题,Shiro相关的文档和教程没少翻.最后 ...
- 使用redis进行基于shiro的session集群共享
之前写过一篇nginx多tomcat负载均衡,主要记录了使用nginx对多个tomcat 进行负载均衡,其实进行负载均衡之前还有一个问题没有解决,那就是集群间的session共享,不然用户在登录网站之 ...
- shiro源码篇 - shiro的session的查询、刷新、过期与删除,你值得拥有
前言 开心一刻 老公酷爱网络游戏,老婆无奈,只得告诫他:你玩就玩了,但是千万不可以在游戏里找老婆,不然,哼哼... 老公嘴角露出了微笑:放心吧亲爱的,我绝对不会在游戏里找老婆的!因为我有老公! 老婆: ...
- 008-shiro与spring web项目整合【二】认证、授权、session管理
一.认证 1.添加凭证匹配器 添加凭证匹配器实现md5加密校验. 修改applicationContext-shiro.xml: <!-- realm --> <bean id=&q ...
- Shiro Quartz之Junit測试Session管理
Shiro的quartz主要API上提供了org.apache.shiro.session.mgt.quartz下session管理的两个类:QuartzSessionValidationJob和Qu ...
- Shiro学习(10)Session管理
Shiro提供了完整的企业级会话管理功能,不依赖于底层容器(如web容器tomcat),不管JavaSE还是JavaEE环境都可以使用,提供了会话管理.会话事件监听.会话存储/持久化.容器无关的集群. ...
- shiro session管理
http://shiro.apache.org/session-management.html Using Sessions The SessionManager Session Timeout Pe ...
- Dubbo学习系列之九(Shiro+JWT权限管理)
村长让小王给村里各系统来一套SSO方案做整合,隔壁的陈家村流行使用Session+认证中心方法,但小王想尝试点新鲜的,于是想到了JWT方案,那JWT是啥呢?JavaWebToken简称JWT,就是一个 ...
随机推荐
- shell getopts用法
eg:sh test.sh -u tom -p 123456: getopts的使用形式:getopts OPTION_STRING VAR: OPTION_STRING:-u,-p这种自定义选项: ...
- 学习1__STM32--FatFS之逻辑盘符与物理盘符
FatFS源代码中的函数逻辑关系 第一 调用函数 f_mount() result = f_mount(&fs, FS_VOLUME_NAND, ); /* Mount a logical d ...
- chattr命令详解
[root@localhost ~]# usermod -L yan[root@localhost ~]# passwd -S yanyan LK 2016-07-11 0 99999 7 -1 (密 ...
- Eclipse Memory Analyzer(MAT)使用
https://user.qzone.qq.com/731573705/blog/1436389384 Eclipse Memory Analyzer(MAT)使用 一.OutOfMemoryErr ...
- Python学习day2 while循环&格式化输出&运算符
day2 运算符-while循环 1.while循环 while循环基本结构; while 条件: 结果 # 如果条件为真,那么循环则执行 # 如果条件为假,那么循环不执行 de ...
- 闲聊javascript继承和原型
javascript继承已经是被说烂的话题了,我就随便聊一点~ 一.javascript的复制继承 javascript的继承有复制继承和原型继承,基于复制继承用的不太多,而且无法通过instance ...
- 商品详情页系统的Servlet3异步化实践
http://jinnianshilongnian.iteye.com/blog/2245925 博客分类: 架构 在京东工作的这一年多时间里,我在整个商品详情页系统(后端数据源)及商品详情页统一 ...
- Docker普通用户不使用sudo提权
解决方法 sudo groupadd docker 添加Docker用户组 sudo gpasswd -a ${USER} docker 添加你的用户到Docker用户组 reboot 重启系统.也可 ...
- vue $emit 用法
1.父组件可以用props传递给子组件. 2.子组件可以利用$emit触发父组件事件. vm.$emit('父组件方法',参数); vm.$on(event,fn); $on监听event事件后运行f ...
- bzoj3238 差异
题目链接 思路 观察题目中的式子,可以发现前两项是定值.所以只需要求出最后一项就行了. 然后题目就转化为了求字符串中所有后缀的\(lcp\)长度之和. 可以想到用后缀数组.在后缀数组上两个后缀的\(l ...
