爪哇玻璃鱼3。十、 以编程方式处理任意HTTPSession的终止
考虑下面的场景。
我在Glassfish 3.1.1上部署了一个Java EE web应用程序(JSF 2.2、JPA、EJB3.0,即使框架在这里并不重要),它有一个登录保护区,我通过标准Glassfish安全机制来保护它
我的商业模式是将对该web应用程序的访问权作为一项服务出售,禁止一个用户名/密码同时进行多次登录。出于这个原因,我在数据库中保留了一列,用户登录时增加,用户注销时减少。此外,我在SessionScoped managed bean中有一个方法,用@PreDestroy注释,它负责在会话过期时减少计数器(通过session timeout属性在web.xml中配置60分钟)
当用户尝试使用大于1的计数器登录时,应用程序会通知他该问题,邀请他先登录上一个工作站
这工作得很好,但我们有越来越多的用户执行他们的操作,关闭浏览器(不注销),然后在会话超时限制内(我们再次将其设置为60分钟)尝试从不同的工作站进行身份验证
在这些情况下,我们希望能够提供关闭与用户直接从新工作站登录相关的所有先前会话的机会(因此,使用自己的会话登录的用户X应该能够请求终止与其帐户逻辑链接的不同会话)。我知道,如果他/她只需等待60分钟,Glassfish将最终终止会话,但我们希望避免来自这个“问题”的支持请求(你知道,很难向非技术用户解释此类内容)
我的第一个计划是将用户HTTPSession的JSSession ID存储在某处,通过存储的JSSession ID访问旧会话(如果有),并根据需要关闭或使其失效。我已经阅读了很多关于这个主题的材料,我发现this SO question显然是我想要的答案(一种将HTTPSession存储在地图中的方法,使用JSSessionID作为键来获取它们)。这看起来很简单,我可以在几分钟内实现这一点,但下面的评论,尤其是@BalusC给出的答案的第二部分,让我想问一下你对我应该如何安全地实现这一点的看法
这是一个最佳实践的问题,你们将如何实现这一点
我不需要代码,只需要您作为JavaEE架构师的意见,或者关于这个主题的某种文档的参考
# 1 楼答案
跟踪数据库中的所有登录(当会话被破坏时,可以使用
HttpSessionListener
删除条目)。确保有一个布尔列“现在应该终止会话!”在DB中,默认为false。当现在给出终止所有其他会话的操作时,将这些会话的布尔值设置为true
。在过滤器中,在每个请求中,检查数据库中的布尔值,并相应地进行处理这样,您就不需要处理所有物理
HttpSession
实例