httpservletrequest - 创建新会话/更改会话 ID
Posted
技术标签:
【中文标题】httpservletrequest - 创建新会话/更改会话 ID【英文标题】:httpservletrequest - create new session / change session Id 【发布时间】:2011-01-19 15:58:16 【问题描述】:我正在维护一个 Java Web 应用程序。
查看登录代码,它通过 HttpServletRequest 的 getSession() 方法从 HttpServletRequest 中获取 HttpSession。 (它使用会话中的一些值进行身份验证)
但是我担心会话固定攻击,所以在使用初始会话后,我想启动一个新会话或更改会话 ID。这可能吗?
【问题讨论】:
【参考方案1】:Servlet 3.0 API 不允许您更改现有会话的会话 ID。通常,为了防止会话固定,您只需创建一个新的并使旧的无效。
您可以像这样使会话无效
request.getSession(false).invalidate();
然后用
创建一个新会话getSession(true)
(getSession()
也应该可以)
显然,如果您想要持久化会话中的数据,则需要将其从第一个会话复制到第二个会话。
注意,对于会话固定保护,通常认为只对身份验证请求执行此操作是可以的。但是更高级别的安全性涉及丢弃旧会话并为每个请求创建一个新会话。
【讨论】:
当之前没有调用 getSession 时,这不应该给出 NullPointerException 吗? 如果您使用getSession()
而不是 getSession(boolean)
,我会支持您。
我的问题是假设会话此时已经存在。谢谢你的好答案。
@BalusC,如果之前不存在,您将创建一个会话并立即将其删除。做什么的? request.getSession(false).invalidate();
带有空检查是正确答案。
所以,这个答案假定您在会话中没有任何其他重要数据,对吗?甚至身份验证令牌也必须传播到新会话,对吗?【参考方案2】:
从 Java EE 7 和 Servlet API 3.1 (Tomcat 8) 开始,您可以使用 HttpServletRequest.changeSessionId() 来实现这种行为。还有一个监听器HttpSessionIdListener
,每次更改后都会调用它。
【讨论】:
Shiro 和 changeSessionId 是一个强大的组合。它允许我编写我的熔岩逻辑而不会分心 'if(success) request.changeSessionId()' 不需要重写,我不需要以上是关于httpservletrequest - 创建新会话/更改会话 ID的主要内容,如果未能解决你的问题,请参考以下文章
org.openqa.selenium.SessionNotCreatedException:无法创建新会话。 (原始错误:请求了一个新会话,但一个正在进行中)