【问题标题】:Browser specific session management浏览器特定的会话管理
【发布时间】:2014-10-12 04:37:23
【问题描述】:

让我解释一下我的场景,

我已经创建了一个 Spring Web 应用程序并部署在 tomcat 上。然后我打开了一个 chrome 浏览器并启动了应用程序。它运行成功。然后我又打开了一个新的浏览器,比如说 IE/Firefox。然后我又重新启动了我的应用程序。然后 Chrome 浏览器上可用的会话应该无效或重定向到登录页面。简单来说,我应该能够一次在一个浏览器中访问我的网页。

有没有办法使用弹簧来实现这一点?还是其他方式??

谢谢 纳文

【问题讨论】:

  • 我怀疑 Java-EE 是否为它提供了任何机制。我建议你使用持久数据机制来存储状态,如果有来自同一个 IP 或用户的另一个请求,你可以使来自另一个浏览器的会话无效。当然,必须将状态推送到较早的浏览器。
  • HTTP 是一种无状态协议。您可以记录登录/用户代理对,然后知道用户是否从其他浏览器登录。不同机器上的同一个浏览器怎么样?
  • Spring Security 允许您限制每个用户的并发会话数。
  • @Scary Wombat:感谢您的意见。

标签: java spring jakarta-ee web-applications session-management


【解决方案1】:

您正在寻找的不是开箱即用的 Java Web Container 功能。但这仍然可以使用一些应用程序逻辑来实现。这是实现此目的的一种方法:

  1. 创建一个过滤器,它将用户名的映射作为键和相应的会话ID存储在某个映射中(您也可以使用数据库);如果您使用地图,请确保使用ConcurrentHashMap
  2. 在身份验证过滤器之后添加此过滤器
  3. 将为所有 URL 调用此过滤器。
  4. 每当请求用户登录时,此过滤器都会简单地添加/覆盖用户名和当前会话 ID 的映射。
  5. 对于所有其他请求(非登录),过滤器将根据用户名检查当前会话 ID 是否与地图中存储的相同。如果是,则继续,否则使会话无效(因为用户已经完成了由不同会话 ID 指示的另一个登录)并使用适当的消息重定向用户。

【讨论】:

    【解决方案2】:

    您没有说明如何进行身份验证。但是由于您已经在使用 Spring,我建议您也使用具有开箱即用的可配置会话管理的 Spring 安全性。

    使用 html 配置,您可以使用(摘自 Spring Security Reference Manual 3.2.x / Security Namespace Configuration / Advanced Web Features / Session Management)要求新会话使来自同一用户的先前会话无效:

    <http>
      ...
      <session-management>
         <concurrency-control max-sessions="1" />
      </session-management>
    </http>
    

    或者新会话将失败:

    <http>
      ...
      <session-management>
         <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
      </session-management>
    </http>
    

    【讨论】:

    • @SergeBallesta:感谢您的解释。它适用于相同的用户概念。但是不同的用户概念呢??
    • 您真的希望一次只需要一个会话,而与登录用户无关?也就是说,如果 userA 有一个活动会话并且 userB 登录到应用程序,那么 userA 的会话应该失效吗?
    猜你喜欢
    • 2010-12-20
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    • 2017-08-03
    • 1970-01-01
    • 2023-04-11
    • 2011-06-03
    相关资源
    最近更新 更多