文档章节

Shiro中获取Cookie

豫华商
 豫华商
发布于 07/07 19:39
字数 942
阅读 111
收藏 0

行业解决方案、产品招募中!想赚钱就来传!>>>

自定义shiro的SessionIdCookie

在使用shiro的时候,曾经有段时间很苦恼,因为我cookie的sessionId经常无故被改,然后抛There is no session with id [xxxx]的异常。我们知道,当请求过来,shiro创建session后,会把sessionId写回到客户端的cookie中。每二个请求过来时,shiro会拿到这个cookie里的sessionId去查找,如果查找不到,就有可能抛There is no session with id的异常。通过抛这个异常的会有两种情况,一种就是我刚才说的,cookie被改写了,因为shiro默认的cookie名叫JSESSIONID,当在web.xml里配置的请求拦截配得不合理时,就有可能被改写。在我的项目中,因为有些静态资源配置了不拦截,就会被容器改写了这个cookie。后来,干脆把cookie的名字改了,不再叫JSESSIONID。还有一种就是浏览器打开很久都没有操作,然后shiro定时清理了不活动的session,这时浏览器再发请求过来,因为session已被清理,也会抛There is no session with id。Shiro的Cookie名称默认是JSESSIONID,与servlet容器冲突。修改Shiro的SessionID即可。

错误信息:

2020-07-07 16:32:33 ERROR Febs-Async-Thread2 org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler Unexpected exception occurred invoking async method: public void com.bjbde.cyberspace.monitor.service.impl.LogServiceImpl.saveLog(org.aspectj.lang.ProceedingJoinPoint,java.lang.reflect.Method,java.lang.String,java.lang.String,long)
org.apache.shiro.session.UnknownSessionException: There is no session with id [521679bc-068a-4e7f-8873-e8f3e1b45e4a]
	at org.apache.shiro.session.mgt.eis.AbstractSessionDAO.readSession(AbstractSessionDAO.java:170)
	at org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSessionFromDataSource(DefaultSessionManager.java:236)
	at org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSession(DefaultSessionManager.java:222)
	at org.apache.shiro.session.mgt.AbstractValidatingSessionManager.doGetSession(AbstractValidatingSessionManager.java:118)
	at org.apache.shiro.session.mgt.AbstractNativeSessionManager.lookupSession(AbstractNativeSessionManager.java:148)
	at org.apache.shiro.session.mgt.AbstractNativeSessionManager.lookupRequiredSession(AbstractNativeSessionManager.java:152)
	at org.apache.shiro.session.mgt.AbstractNativeSessionManager.getAttribute(AbstractNativeSessionManager.java:249)
	at org.apache.shiro.session.mgt.DelegatingSession.getAttribute(DelegatingSession.java:141)
	at org.apache.shiro.session.ProxiedSession.getAttribute(ProxiedSession.java:121)
	at org.apache.shiro.subject.support.DelegatingSubject.getRunAsPrincipalsStack(DelegatingSubject.java:473)
	at org.apache.shiro.subject.support.DelegatingSubject.getPrincipals(DelegatingSubject.java:157)
	at org.apache.shiro.subject.support.DelegatingSubject.getPrincipal(DelegatingSubject.java:153)
	at com.bjbde.cyberspace.monitor.service.impl.LogServiceImpl.saveLog(LogServiceImpl.java:75)
	at com.bjbde.cyberspace.monitor.service.impl.LogServiceImpl$$FastClassBySpringCGLIB$$e63db351.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747)
	at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
	at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
	at java.util.concurrent.FutureTask.run(FutureTask.java)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

更改Cookie的名字方法如下:

配置文件方式


<bean id="shiroSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">

<property name="sessionDAO" ref="sessionDAO"/>

<!-- <property name="sessionValidationScheduler" ref="shiroSessionValidationScheduler"/> -->

<property name="sessionValidationInterval" value="1800000"/> <!-- 相隔多久检查一次session的有效性 -->

<property name="globalSessionTimeout" value="1800000"/> <!-- session 有效时间为半小时 (毫秒单位)-->

<property name="sessionIdCookie.domain" value=".xxx.com"/>

<property name="sessionIdCookie.name" value="jsid"/>

<property name="sessionIdCookie.path" value="/"/>

<!-- <property name="sessionListeners">

<list>

<bean class="com.concom.security.interfaces.listener.SessionListener"/>

</list>

</property> -->

</bean>


代码实现


import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;

@Configuration
@RequiredArgsConstructor
public class ShiroConfig {

	 /**
     * session 管理对象
     *
     * @return DefaultWebSessionManager
     */
    @Bean
    public DefaultWebSessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        Collection<SessionListener> listeners = new ArrayList<>();
        listeners.add(new ShiroSessionListener());
        // 设置 session超时时间
        sessionManager.setGlobalSessionTimeout(febsProperties.getShiro().getSessionTimeout() * 1000L);
        sessionManager.setSessionListeners(listeners);
        sessionManager.setSessionDAO(redisSessionDAO());
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        SimpleCookie simpleCookie = new SimpleCookie();
        simpleCookie.setName("jsid");
        /*simpleCookie.setDomain("xxx.com");
        simpleCookie.setPath("/");*/
        sessionManager.setSessionIdCookie(simpleCookie);
        return sessionManager;
    }


}

我们打开shiro的DefaultWebSessionManager类源码就可以知道,里面有个private Cookie sessionIdCookie;属性,这个就是sessionId的cookie。在DefaultWebSessionManager的构造器里,初始化的名字取的是ShiroHttpSession.DEFAULT_SESSION_ID_NAME,也就是"JSESSIONID",在这里我们不去改源码,只要通过spring改sessionIdCookie的属性即可。

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;

}

在上面的xml配置中,写了sessionIdCookie.domain的值为.xxx.com,这个根据自己的项目而定。这里配置为的是某域名及其二级域名都能共享这个cookie。还有sessionIdCookie.name,这个就是cookie的名字,值为jsid。这样我们就可以看到,cookie会多了一个名字jsid,值为当前session的id的键值。在上面还配置了两个关于session有效期的配置,一个是sessionValidationInterval,表示shiro的定时器多久去检查一次session的有效性,一个是globalSessionTimeout,表示session的有效时长。当然,我们也完全可以息定义定时器,把定时器注入到DefaultWebSessionManager的sessionValidationScheduler属性中,只是个人觉得没这个必要。

豫华商

豫华商

粉丝 4
博文 117
码字总数 44396
作品 0
海淀
高级程序员
私信 提问
加载中
请先登录后再评论。
浏览器中的scheme解释器--SchemeScript

一个用javascript实现的scheme解释器,可以运行在浏览器中或node.js中。 刚刚看到编译原理与实践第二章,一时兴起,想写个以前就想写的scheme的解释器。昨天晚上开始写,到刚才为止,接近一天...

zoowii
2012/11/01
1.1K
0
垂直爬虫--WebMagic

webmagic的是一个无须配置、便于二次开发的爬虫框架,它提供简单灵活的API,只需少量代码即可实现一个爬虫。 以下是爬取oschina博客的一段代码: Spider.create(new SimplePageProcessor("h...

黄亿华
2013/06/13
12.8W
84
在C++中使用Lua

http://www.cppprog.com/2009/0209/62.html

Waiting4you
2009/05/05
1K
0
SmartGWT学习整理 2、理解核心中的核心DataSource

SmartGWT学习整理 2、理解核心中的核心DataSource DataSource之所以重要,是因为它负责所有的与服务器的数据交互,几乎所有的控件都离不开它。 可以这样说,理解了DataSource就掌握了SmartGW...

st97
2010/11/16
2K
2
理解Swift中Optional类型-有和无的哲学

原文连接:http://blog.barat.cc/ios/understanding-swift-optional/ nil的遗憾 当某个变量或表达式没有任何内容时,在Objective-C中可以使用来表示。在Objective-C中是一个「野孩子」,voi...

巴拉迪维
2015/11/19
1.8K
9

没有更多内容

加载失败,请刷新页面

加载更多

SPSSAU 付费数据研究报告服务

SPSSAU-付费数据分析报告服务(周老师提供) 本文分享自微信公众号 - SPSSAU(spssau)。 如有侵权,请联系 support@oschina.cn 删除。 本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起...

SPSSAU
2017/11/08
0
0
芋艿-springcloud gateway

http://www.iocoder.cn/Spring-Cloud/Spring-Cloud-Gateway/?github springcloud gateway 官方文档 https://cloud.spring.io/spring-cloud-gateway/reference/html/#gatewayfilter-factories......

Java搬砖工程师
20分钟前
5
0
新零售小程序制作流程

最近有很多小伙伴们都在观望新零售小程序,其实新零售小程序制作还是比较简单的,只要你能熟知以下的新零售小程序制作流程,你也可以制作出属于自己的小程序。下面木鱼小铺(www.muyu007.cn)...

木鱼小铺小程序1
21分钟前
0
0
bat增加自定义参数

#xxx.bat --tag=dev1010 --context=3 --cpu=3 --memory=3 --build=1 --update=1 --api-version=1 @echo off setlocal enabledelayedexpansion set COMMANSLINE="%" :STR_VISTOR for /f "toke......

_snake_
23分钟前
3
0
谷歌SEO推广团队,这样管理更高效!

如今不论是外贸企业还是专业的海外推广公司都会组建自己的Google SEO推广团队,可以更有效的做好网站SEO,但是要发挥谷歌SEO推广团队的最大效能,我们并不能随意的让团队成员听之任之,随波逐...

一尘SEO
25分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部