【问题标题】:Destroy a session of another user in spring在春季销毁另一个用户的会话
【发布时间】:2013-06-11 01:21:33
【问题描述】:

在我的应用程序中,我有一个可以删除用户的管理员。所以当我从管理会话中删除一个用户时,我希望被删除的用户应该自动注销。 我知道我删除的用户的会话 ID,但我不知道如何使用会话 ID 使会话无效。

我想要类似:invalidate(SessionId);

有没有可能?我认为可以使用过滤器并在每次请求时检查数据库,但是否有另一种方法不需要在每个 httprequest 上检查数据库?

谢谢。 :D

【问题讨论】:

  • 请问如何检索用户的会话 ID?

标签: spring session spring-security sessionid


【解决方案1】:

我想我看到了一个使用 Spring Security 基础架构的解决方案,带有 SessionRegistry 类。

您必须在web.xml 中注册HttpSessionEventPublisher

<listener>
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>

在您的 Spring 配置中,声明 SessionRegistry。

<bean id="sessionRegistry"
     class="org.springframework.security.core.session.SessionRegistryImpl" />

在您的管理控制台中,您必须使用SessionRegistry 来检索用户的SessionInformation 并调用expireNow。在用户的下一个请求中,servlet 过滤器应该使 HttpSession 过期。 SessionInformation 的 javadoc 对它的工作原理有一些解释。

如果有帮助,请告诉我们。

【讨论】:

  • 我遇到了问题,我注册了会话调用 sessionRegistry.registerNewSession(String session, Object principal) 当我删除用户时,我正确地获取了会话并调用了 sessionInformation.expireSession() 在控制器中,但它没有用。仍在工作的用户会话
  • 我再次阅读了docs,我认为您还必须将&lt;session-management ...&gt; 添加到Spring 安全配置的&lt;http&gt; 部分。我希望它会有所帮助。
  • 为什么不将此添加到答案中?
【解决方案2】:
// to end a session of a user:
List<SessionInformation> sessions = sessionRegistryImpl.getAllSessions(user, false);
sessionRegistryImpl.getSessionInformation(sessions.get(0).getSessionId()).expireNow();

// note: you can get all users and their corresponding session Ids: 
List<Object> users = sessionRegistryImpl.getAllPrincipals();
List<String> sessionIds = new ArrayList<>(users.size());

for (Object user: users) {
    List<SessionInformation> sessions = sessionRegistryImpl.getAllSessions(user, false);
    sessionIds.add(sessions.get(0).getSessionId());
}

【讨论】:

  • 我必须按照 LaurentG 写的去做吗?
  • @Alex78191,我们的答案几乎相同。在这两种情况下,您都需要调用expireNow 方法。
  • 我应该在web.xml中注册HttpSessionEventPublishe并声明SessionRegistry吗?
  • 不记得了。我使用的不是 web.xml,而是 java config。
  • 我相信您可能希望如上所述使用户的会话过期,但也要删除它们(removeSessionInformation(sessionid)。
【解决方案3】:

除了@LaurentG 的建议外,还需要在您的 spring 配置文件中添加以下内容:

<session-management>
    <concurrency-control session-registry-alias="sessionRegistry" />
</session-management>

让它工作。 @zygimantus 答案也可用于访问会话数据。

【讨论】:

  • &lt;concurrency-control session-registry-alias="sessionRegistry" /&gt;&lt;bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/&gt; 相同
【解决方案4】:

除了如上所述使用户过期之外,您可能还希望将其从注册表中删除:

// expire and remove the user's sessions from Spring session registry
List<Object> principals = sessionRegistry.getAllPrincipals();
for (Object principal : principals) {
    List<SessionInformation> sessions = sessionRegistry.getAllSessions(principal, true);
    for (SessionInformation sessionInfo : sessions) {
        if (authentication.getPrincipal().equals(sessionInfo.getPrincipal())) {
           if (!sessionInfo.isExpired()) sessionInfo.expireNow();
           sessionRegistry.removeSessionInformation(sessionInfo.getSessionId());
        }
    }
}

如果使用 xml 配置来连接你的 Spring Session Registry,它可能看起来像这样:

<beans:bean id="sessionRegistry"
    class="org.springframework.security.core.session.SessionRegistryImpl" />

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-27
    • 2010-10-08
    • 1970-01-01
    • 2019-12-08
    • 2016-11-06
    • 2015-01-02
    • 2012-04-22
    相关资源
    最近更新 更多