【问题标题】:Glassfish 3.X, programmatically handle the termination of arbitrary HTTPSessionGlassfish 3.X,以编程方式处理任意 HTTPSession 的终止
【发布时间】:2014-02-01 04:56:59
【问题描述】:

考虑以下场景。

我有一个 Java EE Web 应用程序(JSF 2.2、JPA、EJB 3.0,即使框架在这里无关紧要)部署在 Glassfish 3.1.1 上,带有登录保护区,我通过标准 Glassfish 保护它安全机制。

我的商业模式是基于销售对这个 Web 应用程序的访问作为一项服务,禁止多个用户同时登录一个用户名/密码。出于这个原因,我在我的数据库中保留了一个列,我在用户登录时递增,在用户注销时递减。此外,我在使用 @PreDestroy 注释的 SessionScoped 托管 bean 中有一个方法,它负责在会话到期时递减计数器(通过 session-timeout 属性在 web.xml 中配置 60 分钟)。

当用户尝试使用大于 1 的计数器登录时,应用程序会通知他该问题,邀请他先注销之前的工作站。

这工作得很好,但是我们有越来越多的用户执行他们的操作,关闭浏览器(不注销),然后尝试在会话超时限制内从不同的工作站进行身份验证(再次,我们设置为 60 分钟)。

在这些情况下,我们希望能够提供关闭与用户直接从新工作站登录相关联的所有先前会话的机会(因此用户 X 使用他自己的会话登录,应该能够要求终止与其帐户逻辑关联的不同会话)。我知道如果他/她只等待 60 分钟,会话最终将被 Glassfish 终止,但我们希望避免来自这个“问题”的支持请求(你知道很难向非技术用户)。

我的第一个计划是将用户 HTTPSession 的 jsession ID 存储在某处,通过存储的 jsession ID 访问旧会话(如果有),并按需关闭或使它们无效。我已经阅读了很多关于这个主题的材料,我发现this SO question 显然是我正在寻找的答案(一种将 HTTPSession 存储在地图中的方法,使用 jsessionID 作为键来获取它们)。这看起来很简单,我可以在几分钟内实现它,但是下面的 cmets,尤其是来自@BalusC 的答案的第二部分,促使我询问你对如何以安全的方式实现它的意见。

这是一个最佳实践问题,你们将如何实施?

我不需要代码,只需要您作为 Java EE 架构师的意见或有关该主题的某种文档的参考。

【问题讨论】:

    标签: java jsf session jakarta-ee glassfish


    【解决方案1】:

    跟踪数据库中的所有登录(您可以使用HttpSessionListener 在会话被破坏时删除条目)。确保你有一个布尔列“现在应该终止会话!”在默认为 false 的数据库中。当给出立即终止所有其他会话的操作时,将这些会话的布尔值设置为true。在过滤器中,针对每个请求,检查 DB 中的布尔值并进行相应处理。

    这样您就不需要拥有所有物理HttpSession 实例的句柄。

    【讨论】:

    • 好的,我明白你的意思了。而不是销毁所有旧会话,您建议在逻辑上使它们无效,从而允许访问新会话。即使我对过滤器作用于每个请求所引入的额外开销有些担心,这似乎也可以。我接受你的回答,如果它按预期工作,我会通知你。
    猜你喜欢
    • 1970-01-01
    • 2022-11-12
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    相关资源
    最近更新 更多