2010-02-22 252 views
31

我正在维护一个Java Web应用程序。httpservletrequest - 创建新会话/更改会话Id

查看登录代码,它通过HttpServletRequest的getSession()方法从HttpServletRequest中获取HttpSession。 (它使用会话中的一些值进行身份验证)

但是我担心会话修复攻击,所以在使用初始会话之后,我想要启动新会话或更改会话ID。这可能吗?

回答

37

Servlet 3.0 API不允许您更改现有会话上的会话ID。通常情况下,为了防止会话固定,您只需要创建一个新会话并使旧会话无效。

您可以作废这样

request.getSession(false).invalidate(); 

一个会话,然后用

getSession(true)getSession()应该也可以工作)创建一个新的会话

显然,如果你在会话中有一个数据你想坚持下去,你需要将它从第一次会议复制到第二次会议。

请注意,对于会话固定保护,通常认为只需在身份验证请求上执行此操作即可。但更高级别的安全性涉及抛弃旧会话并针对每个请求进行新会话。

+3

当getSession之前没有被调用过,是不是应该给出NullPointerException? – FRotthowe 2010-02-22 14:36:58

+0

的确如此,但我认为我们假设会议存在。 – pablochan 2010-02-22 14:38:08

+3

如果您使用'getSession()'而不是'getSession(boolean)'',我会鼓励您。 – BalusC 2010-02-22 14:41:11

23

由于Java EE 7和Servlet API 3.1(Tomcat 8)可以使用HttpServletRequest.changeSessionId()来实现此类行为。还有一个听众HttpSessionIdListener将在每次更改后调用。

+0

Shiro和changeSessionId是一个强大的组合。它允许我写我的熔岩逻辑没有分心'如果(成功)request.changeSessionId()'不需要重写,我是nere – lrn2prgrm 2016-11-24 09:16:09