我尝试使用基于会话的登录与群集中的Java servlet(3.x)环境同时阻止来自同一用户帐户的多个活动登录。我使用带有this official AWS library的Tomcat 8来实现会话管理器,该会话管理器使用DynamoDB保存会话以进行存储。
会话管理器设置非常简单,只需要事先使用名为sessionId
的散列键设置DynamoDB表,并且没有范围键(或者库可以根据需要为您创建表) 。
为了防止来自同一用户帐户的多个活动登录,在登录过程中,我想以某种方式查询尝试登录的特定用户的任何活动会话。由于servlet框架不允许按会话ID进行查询,因此我现在想到的最好的方法是在DynamoDB表(会话数据库)中添加一个额外的索引属性来存储会话的用户名,并在创建会话时将该属性添加到会话数据,例如HttpSession#setAttribute(String, String)
然后,当有人尝试登录时,我可以向DynamoDB查询与指定用户名匹配的任何当前会话。如果我得到匹配,那么我可以从DynamoDB中删除该会话并创建一个新会话。因此,当某人已经从另一台计算机(或同一台计算机上的其他浏览器)登录时,该会话将失效,新的登录会话将是唯一的活动会话。
我的问题是这是否合适。我担心如果我自己删除会话数据库中的条目,我会绕过会话管理器,因此我不知道这是否会导致问题。当我自己删除会话时,我不会以正常方式使会话无效,即调用HttpSession#invalidate()
这种方法是否正常,或者是否有其他方法可以指示会话管理器(或触发它) )使会话无效?
关于@ramp在评论中提出的解决方案(使用标记会话为陈旧的附加属性)引发了另一个问题。手动添加/更新会话数据库条目的属性是否安全?我可以安全地阅读稍后手动添加的会话属性,例如HttpSession#getAttribute(String)