【Shiro】shiro的Session管理
- 1. Session管理介绍
- 2. JavaSE环境下
- 3. JavaEE环境下
- 4. Session监听
- 5. Session检测
1. Session管理介绍
shiro作为⼀款安全管理框架,对状态保持有很强的需要。
⽐如最常⽤的⽤户认证,就必需状态的保持,以及其他的⼀些功能实现的需要。
【shiro需要:认证中的 记住我中的⽤户名 正式登陆的⽤户名 】
【 开发者需要:其他功能中需要存⼊session的值 】
shiro提供了⼀整套session管理⽅案.
1. shiro的session⽅案和任何容器⽆关
(如servlet容器);
2. javaSE也可以使⽤;相关组件都是pojo对ioc极其友好(⽅便的管理对象和满⾜依赖关系,定制参数)
3. 可以⽅便的扩展定制存储位置(内存,缓存,数据库
等)
4. 对web透明
⽀持:⽤了shiro的session后,项⽬中关于session的代码完全不⽤任何改动
5. 提供了全⾯的session监听
机制,和session检测
机制,对session可以细粒度操作
即,使⽤了shiro后,采⽤shiro的session⽅案是最优的⽅案。
2. JavaSE环境下
shiro 的session管理⽅案,可以在javaSE中使⽤,但是实⽤价值不⼤。毕竟session对应的是会话管理
Subject subject = SecurityUtils.getSubject();
//获取session
Session session = subject.getSession();
//session超时时间,单位:毫秒;0,⻢上过期;正数,则空闲对应毫秒后过期;负数,则不会过期
session.setTimeout(10000);
//session存、取值
session.setAttribute("name","siyi"); session.getAttribute("name");
//获取sessionID
getSession().getId();
// 销 毁 session session.stop();
原理,核⼼对象:
1.SimpleSession
Session的实现类,完成session基本功能。
2.SimpleSessionFactory
⽣产SimpleSession
3.SessionDAO
默认的实现类:MemorySessionDAO,由SessionManager创建,
负责存储所有session对象,存储位置:内存
4.DefaultSessionManager
由SecurityManager创建,负责创建、管理SessionFactory和SessionDAO。
//核⼼类演示: ( ops:实际开发不⽤⼿动创建,shiro会初始化 )
//通过SecurityManager 获得 SessionManager
DefaultSessionManager sessionManager = (DefaultSessionManager)securityManager.getSessionManager();
//通过SessionManager获得SessionFactory
SimpleSessionFactory sessionFactory = (SimpleSessionFactory) sessionManager.getSessionFactory();
//通过SessionManager获得SessionDAO
MemorySessionDAO sessionDAO = (MemorySessionDAO)sessionManager.getSessionDAO();
//通过SessionFactory获得Session
SimpleSession session1 = (SimpleSession) sessionFactory.createSession(null);
//通过Session做具体操作session1.setAttribute("name","zhangsan"); System.out.println(session1.getAttribute("name"));
3. JavaEE环境下
在spring配置文件中增加session管理相关配置。
<!-- 增加session管理相关配置 -->
<!-- 会话Cookie模板 默认可省-->
<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<!-- cookie的 key="sid" -->
<property name="name" value="JSESSIONID"/>
<!-- 只允许http请求访问cookie -->
<property name="httpOnly" value="true"/>
<!-- cookie过期时间,-1:存活⼀个会话 ,单位:秒 ,默认为-1-->
<property name="maxAge" value="-1"/>
</bean>
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!-- 默认值和配置中给出的⼀致,所bean:sessionIdCookie 可以省略 -->
<property name="sessionIdCookie" ref="sessionIdCookie"/>
<!-- session全局超时时间, 单位:毫秒 ,30分钟 默认值为1800000-->
<property name="globalSessionTimeout" value="1800000"/>
</bean>
<!-- 将sessionManager关联到SecurityManager -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
...
<!-- 增加配置sessionManager -->
<property name="sessionManager" ref="sessionManager"/>
</bean>
4. Session监听
session有三个核⼼过程:创建、过期、停⽌
过期: session的默认过期时间为30分钟。通过⽐对最近⼀次使⽤时间和当前使⽤时间判断 session不会⾃动报告过期,需检测器检测时,或再次访问时,才可以识别是否过期并移除。
停⽌: ⽤户主动logout
;主动调⽤session.stop()
; 两种情况会将session标志为停⽌状态。
// 定义监听类 exentends SessionListenerAdapter
public class MySessionListener extends SessionListenerAdapter{
//当有session创建时 触发
@Override
public void onStart(Session session) {
System.out.println("session:"+session.getId()+" start");
}
//当有session停⽌时 触发
@Override
public void onStop(Session session) {
System.out.println("session:"+session.getId()+" stop");
}
//当有session过期时 触发
// 但不会主动触发,需要再次访问时,即⼜要使⽤session时才会发现session过期,并触发。
@Override
public void onExpiration(Session session) {
System.out.println("session:"+session.getId()+" expired");
}
}
配置监听类,关联给SessionManager
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
...
<property name="sessionListeners">
<list>
<bean class="com.siyi.listener.MySessionListener"></bean>
</list>
</property>
...
</bean>
5. Session检测
⽤户如果没有主动退出登录,只是关闭浏览器,则session是否过期⽆法获知,也就不能停⽌session。 为此,shiro提供了session的检测机制,可以定时发起检测,识别session过期 并停⽌session。
<!-- sessionManager默认开启session检测机制 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
...
<!-- 开启检测器,默认开启 -->
<property name="sessionValidationSchedulerEnabled" value="true"/>
<!--- 检测器运⾏间隔,单位:毫秒 默认1⼩时
//检测到过期后,会直接将session删除
protected void afterExpired(Session session) { if (isDeleteInvalidSessions()) {
delete(session);
}
}
-->
<property name="sessionValidationInterval" value="3600000"/>
...
</bean>
如上,通过检测器,定时的检测session,并及时移除⽆效session,释放资源。