`
jinnianshilongnian
  • 浏览: 21424333 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2403176
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:2996176
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5630413
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:257187
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1592662
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:248795
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5845661
Group-logo
跟我学Nginx+Lua开...
浏览量:697478
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:779851
社区版块
存档分类
最新评论

集成Shiro后当遇到404错误时会丢失session

阅读更多

场景:

1、首先登录成功后访问正常页面没有问题的;

2、接着访问一个不存在的页面,即跳到相应的404页面,假设我的页面是jsp的;

3、再刷新一下就会又跳到登录页面。

 

场景分析:

1、首先登录成功,假设JSESSIONID=e688f231-c0f0-4757-b85b-9ff1e62221b3;

2、接着访问一个不存在的页面,提交的JSESSIONID=e688f231-c0f0-4757-b85b-9ff1e62221b3;即提交的JSESSIONID和登录成功的一样;没什么问题;

3、接着随便访问一个地址,会得到JSESSIONID=19eqzaptfpxad17y06dz3uc6xz;两次JSESSIONID不一样且格式不类似,【1、2】步骤的明显是Java UUID生成的key;而第二个则像是如Jetty容器生成的;

4、为什么呢?

 

技术分析:

1、首先如果登录成功,Shiro的DefaultWebSessionManager会默认通过如下方式添加JSESSIONID Cookie到响应:

    private void storeSessionId(Serializable currentId, HttpServletRequest request, HttpServletResponse response) {
        if (currentId == null) {
            String msg = "sessionId cannot be null when persisting for subsequent requests.";
            throw new IllegalArgumentException(msg);
        }
        Cookie template = getSessionIdCookie(); //此处得到JSESSIONID的一个cookie模板
        Cookie cookie = new SimpleCookie(template);
        String idString = currentId.toString();
        cookie.setValue(idString);
        cookie.saveTo(request, response);
        log.trace("Set session ID cookie for session with id {}", idString);
    }

 

2、如果客户端访问时会带着个Cookie回来;但是注意:容器不认识的(Web容器并没有真正创建HttpSession);Shiro默认情况下会生成自己的一套Session,默认是MemorySessionDAO;即放到内存中的;和Web容器没有任何关系;

 

3、 接着访问一个错误的页面(如jsp);此时到了Shiro过滤器,过滤器通过;然后最后forward到这个错误页面;大家应该知道默认情况下jsp页面是需要session的;所以此时jsp会调用request.getSession() 此时创建了一个Session;这会往Cookie写JSESSIONID的;

 

如何解决呢?

1、换一个新的session key,如uid; 推荐这种做法;

2、错误页面 设置<%@ page session="false' %>;

3、给shiro filter配置<dispatcher>ERROR</dispatcher>,然后在其filterChainDefinitions中添加/WEB-INF/jsp/error/error = anon;

 

 

 

9
2
分享到:
评论
9 楼 dufangpu 2016-06-17  
我是继承了DefaultWebSessionManager,然后构造方法

super();
this.getSessionIdCookie().setName("JSESSIONID_SHIRO");

测试是可以的,cookie里面会增加JSESSIONID_SHIRO

不知道对不对,先这样搞吧,现在用还没问题。。。  
8 楼 shuai0420 2014-05-08  
请问大牛,怎么换session key?
7 楼 我心悠悠 2014-04-24  
jinnianshilongnian 写道
lyq881209 写道
forward到404页面时传递的request已经是shiro封装过的,获取的session是shiro的session,怎么是容器生成的session?

因为tomcat发现JSESSIONID对应的session它没有(是shiro管理的)
怎么解决这个问题?我现在系统已出错就到登陆页面去了。。。
6 楼 jinnianshilongnian 2014-03-14  
lyq881209 写道
forward到404页面时传递的request已经是shiro封装过的,获取的session是shiro的session,怎么是容器生成的session?

因为tomcat发现JSESSIONID对应的session它没有(是shiro管理的)
5 楼 lyq881209 2014-03-13  
forward到404页面时传递的request已经是shiro封装过的,获取的session是shiro的session,怎么是容器生成的session?
4 楼 jinnianshilongnian 2014-01-10  
ufohjl 写道
jinnianshilongnian 写道
ufohjl 写道
默认的好像是ServletContainerSessionManager

我使用这个 DefaultWebSessionManager 就会有这个问题的

嗯啊 确实是这样!
那岂不是在用DefaultWebSessionManager 的时候调用javax.servlet.http.HttpSession接口也不能正确获取到sesison,取而代之要用org.apache.shiro.session.Session?

最好不要依赖于HttpSession,而是自己实现一个
3 楼 ufohjl 2014-01-10  
jinnianshilongnian 写道
ufohjl 写道
默认的好像是ServletContainerSessionManager

我使用这个 DefaultWebSessionManager 就会有这个问题的

嗯啊 确实是这样!
那岂不是在用DefaultWebSessionManager 的时候调用javax.servlet.http.HttpSession接口也不能正确获取到sesison,取而代之要用org.apache.shiro.session.Session?
2 楼 jinnianshilongnian 2014-01-09  
ufohjl 写道
默认的好像是ServletContainerSessionManager

我使用这个 DefaultWebSessionManager 就会有这个问题的
1 楼 ufohjl 2014-01-09  
默认的好像是ServletContainerSessionManager

相关推荐

Global site tag (gtag.js) - Google Analytics