6

我们有一个使用 struts2、spring 和 hibernate 开发的 web 应用程序。

该应用程序需要一个用户只能从一个浏览器登录的功能。

假设用户 x, 在 pc-1 浏览器 ff 上登录,那么他无法从任何其他地方登录。

我通过实现会话映射进行了尝试,并将会话存储在全局映射中,但是当用户注销并尝试再次登录时这会失败。

如果用户没有注销和会话超时,即使它严重失败,但地图没有被清除。

实现此功能的任何更好的想法。

我们不想阻止用户登录,但不希望用户通过允许他共享信用并允许多个用户使用相同的登录来利用应用程序。

4

8 回答 8

14

由于您已经在使用 Spring,我建议您将应用程序与 Spring Security 集成。

Spring security 允许您定义每个用户同时允许的最大会话数。

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

如果在具有有效会话的用户尝试再次登录时设置,它将通知用户最大并发访问设置为 1。

在 Spring Security 的参考文档中阅读更多内容:v3.2.xv4.2.xv5.1.x

如果弹簧安全不是您的选择,那么:

  1. 使用SessionInterceptor将检查会话有效性,如果会话有效,它将检查用户是否已经登录到应用程序(为此,您必须在某处维护会话,例如每次成功登录的数据库),如果找到有效登录,使用自定义消息再次将用户重定向到登录页面,或注销已经有效的会话,然后将他重定向到再次登录。如果您注销较早的会话,则意味着该浏览器会话中的任何后续操作都必须处理无效会话。

  2. 如果您也在Servlet应用程序中使用 Interceptor,那么 Interceptor 将不适合您,在这种情况下,您应该使用 aFilter并按照上面针对 Interceptor 详述的相同步骤进行操作。

于 2012-05-28T10:46:00.827 回答
2

最好的解决方案是在用户登录新会话时从其他会话中注销。通常情况下,用户在关闭浏览器时不会注销并限制他登录其他窗口将是陷阱。

自动关闭任何以前的用户会话是好的,因为在正常使用中是没有问题的,但是在共享登录名和密码时,没有两个人可以同时使用您的应用程序。

于 2012-05-28T10:24:44.210 回答
1

Create a map. At the time of logging check that user id is present into that map or not. If its not exist then put user id into map, at the time of logout remove that user id.

于 2012-05-28T12:08:42.753 回答
1

在登录时为用户提供与用户数据一起存储的生成的 ID/cookie(sessionid 即可)。如果用户使用旧 ID/cookie 向服务器发出请求,则说他在其他地方登录。

反过来,禁止新的登录尝试也有其缺点——正如您所经历的那样。

于 2012-05-28T10:23:27.703 回答
0

在 servlet 上下文中维护用户堆栈,因为它将是 web 容器的堆栈。在用户登录之前执行检查,如果在 servlet 上下文中找到用户名将他重定向到登录页面。

于 2014-03-03T13:47:55.580 回答
0

老实说,我会重新审视您必须将用户限制为一次登录的原因。虽然阻止他们从两个不同的浏览器登录很容易 - 提供的任何建议都可以工作 - 如果可以的话,Spring Security 选项是最容易实现的 - 当您的用户打开第二个选项卡时它们都会崩溃浏览器。这被认为是同一会话的一部分。

于 2012-05-28T11:06:08.050 回答
0

您应该做的就是在数据库 userprofile 表中添加一个字段:alreadyLogin。如果用户登录,则设为 Y。如果用户注销,则设为 N。现在每次用户尝试从新位置登录时,检查此值并阻止登录,如果值为 Y。

于 2019-03-29T06:53:10.967 回答
0

正如许多人所说,您可以拥有 (sessionId, user) 的活动用户的 Map<String, User> (静态 Map 或更好的 ServletContext 中的属性)。

当用户尝试登录时,首先检查theMap.values()中是否存在,如果可以,将其添加到theMap中。

不是在注销时从theMap中删除,而是实现一个javax.servlet.http.HttpSessionListener,然后在sessionDestroyed方法上,从中删除项目(该方法的参数为您提供 sessionId)。这样,如果用户关闭浏览器,在会话超时时间之后,它将自动被删除。

注销时,使会话无效,因此它将被销毁,并再次执行此侦听器。

不要忘记将侦听器添加到您的web.xml中。

于 2021-12-12T21:07:57.797 回答