【问题标题】:httpservletrequest - create new session / change session Idhttpservletrequest - 创建新会话/更改会话 ID
【发布时间】:2011-01-19 15:58:16
【问题描述】:

我正在维护一个 Java Web 应用程序。

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

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

【问题讨论】:

    标签: java session servlets


    【解决方案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()' 不需要重写,我不需要
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 2013-02-17
    • 2015-10-04
    • 2014-04-15
    相关资源
    最近更新 更多