首先我们看Shiro的会话管理器的配置
<!-- shiro会话管理 -->
<!-- 即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境的,也可以是如 Web 环境的 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="cacheManager" ref="redisCacheManager"/>
<property name="sessionDAO" ref="redisSessionDAO"/>
<!-- <property name="sessionIdCookie" ref="simpleCookie"/> -->
<!-- 全局的会话信息时间,,单位为毫秒 -->
<property name="globalSessionTimeout" value="1800000"/>
<!-- 检测扫描信息时间间隔,单位为毫秒-->
<property name="sessionValidationInterval" value="60000"/>
<!-- 是否开启扫描 -->
<property name="sessionValidationSchedulerEnabled" value="false"/>
<!-- 去掉URL中的JSESSIONID -->
<property name="sessionIdUrlRewritingEnabled" value="true"/>
</bean>
这里是使用DefaultWebSessionManager默认的Cookie配置
部分源代码
public class DefaultWebSessionManager extends DefaultSessionManager implements WebSessionManager {
private static final Logger log = LoggerFactory.getLogger(DefaultWebSessionManager.class);
private Cookie sessionIdCookie;
private boolean sessionIdCookieEnabled;
private boolean sessionIdUrlRewritingEnabled;
public DefaultWebSessionManager() {
Cookie cookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
cookie.setHttpOnly(true); //more secure, protects against XSS attacks
this.sessionIdCookie = cookie;
this.sessionIdCookieEnabled = true;
this.sessionIdUrlRewritingEnabled = true;
}
}
这里可以看出Cookie cookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);内部默认创建了一个Cookie。
继续看
public SimpleCookie(String name) {
this();
this.name = name;
}
而ShiroHttpSession.DEFAULT_SESSION_ID_NAME="JSESSIONID";
问题来了--》Session失效问题这里为什么为导致Session失效呢?
因为与SERVLET容器名冲突, 如JETTY, TOMCAT 等默认JSESSIONID, 当跳出SHIRO SERVLET时如ERROR-PAGE容器会为JSESSIONID重新分配值导致登录会话丢失效。
因此这里需要自己配置Cookie
<!-- shiro会话管理 -->
<!-- 即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境的,也可以是如 Web 环境的 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="cacheManager" ref="redisCacheManager"/>
<property name="sessionDAO" ref="redisSessionDAO"/>
<property name="sessionIdCookie" ref="simpleCookie"/>
<!-- 全局的会话信息时间,,单位为毫秒 -->
<property name="globalSessionTimeout" value="1800000"/>
<!-- 检测扫描信息时间间隔,单位为毫秒-->
<property name="sessionValidationInterval" value="60000"/>
<!-- 是否开启扫描 -->
<property name="sessionValidationSchedulerEnabled" value="false"/>
<!-- 去掉URL中的JSESSIONID -->
<property name="sessionIdUrlRewritingEnabled" value="true"/>
</bean>
<!-- sessionIdCookie的实现,用于重写覆盖容器默认的JSESSIONID -->
<bean id="simpleCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<!-- 设置Cookie名字, 默认为: JSESSIONID 问题: 与SERVLET容器名冲突, 如JETTY, TOMCAT 等默认JSESSIONID,
当跳出SHIRO SERVLET时如ERROR-PAGE容器会为JSESSIONID重新分配值导致登录会话丢失! -->
<property name="name" value="SHIRO-COOKIE"/>
<!-- JSESSIONID的path为/用于多个系统共享JSESSIONID -->
<!-- <property name="path" value="/"/> -->
<!-- 浏览器中通过document.cookie可以获取cookie属性,设置了HttpOnly=true,在脚本中就不能的到cookie,可以避免cookie被盗用 -->
<property name="httpOnly" value="true"/>
</bean>
好了,这里Shiro配置Cookie就完成了。
此外,如果要配置多个系统共享Session,放开Cookie中的注释即可。
<!-- sessionIdCookie的实现,用于重写覆盖容器默认的JSESSIONID -->
<bean id="simpleCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<!-- 设置Cookie名字, 默认为: JSESSIONID 问题: 与SERVLET容器名冲突, 如JETTY, TOMCAT 等默认JSESSIONID,
当跳出SHIRO SERVLET时如ERROR-PAGE容器会为JSESSIONID重新分配值导致登录会话丢失! -->
<property name="name" value="SHIRO_COOKIE"/>
<!-- JSESSIONID的path为/用于多个系统共享JSESSIONID -->
<property name="path" value="/"/>
<!-- 浏览器中通过document.cookie可以获取cookie属性,设置了HttpOnly=true,在脚本中就不能的到cookie,可以避免cookie被盗用 -->
<property name="httpOnly" value="true"/>
</bean>
这样多个系统就能共享Session了。
What a meaningless sense if losing myself,though owning all of the world.