如何在Spring Security中注销所有已登录的用户?

20
我希望能够通过编程注销所有已登录的用户。如何在某个事件中强制注销所有用户?

我想要实现通过编程注销所有已登录的用户。在某种事件发生时,您如何强制注销所有用户?


回答仅描述了如何获取有关活动会话的信息,但没有说明如何使其无效。 - gstackoverflow
@gstackoverflow - 答案中提到要在活动会话上调用expireNow()来导致注销。你还需要其他的东西吗? - Neil Smithline
@Neil Smithline的回答没有提到如何获取这个会话。因此,答案不完整,作者不接受。 - gstackoverflow
2个回答

18

首先在web.xml中定义HttpSessionEventPublisher

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

然后在您的spring security.xml文件中定义<session-management>

现在,在您的控制器方法中使用SessionRegistry来使所有会话无效。以下代码检索所有活动会话。

List<SessionInformation> activeSessions = new ArrayList<SessionInformation>();
    for (Object principal : sessionRegistry.getAllPrincipals()) {
        for (SessionInformation session : sessionRegistry.getAllSessions(principal, false)) {
            activeSessions.add(session);
        }
    }

在每个活动会话中,您可以调用expireNow()方法使其过期或失效。


@Maksym Demidas,我如何通过SessionInformation获取Session - gstackoverflow
答案仅描述了如何获取有关活动会话的信息,但未描述如何使其无效。 - gstackoverflow
@gstackoverflow 在Servlet API中,没有通过SessionInformation获取Session的方法(而且有很好的理由 - 这不是安全操作)。如果您真的需要它,可以尝试手动解决问题(类似于这样的方式:https://dev59.com/fnA75IYBdhLWcg3w0cjx#3092495) - Maksym Demidas
@Maksym Demidas,实际上我搜索了以下信息:http://stackoverflow.com/a/32477322/2674303 - gstackoverflow

0
Ketan 给出了你所寻找的答案,如果你更改第二个 for 循环并使用 session.expireNow(); 替代 activeSessions.add(session);,那么你将得到所有活动会话已过期的结果。

我在哪里可以找到session? - gstackoverflow
如果您仔细阅读Ketan的示例代码,您会发现session是从sessionRegistry.getAllSessions方法获取的。 - malaguna
请注意并仔细查看返回类型。 - gstackoverflow
你指的是什么返回类型?getAllSessions 返回一个 List<SessionInformation>,在 SessionInformation 上你可以使用 expireNow() 方法来使会话过期。 - malaguna
1
不好意思,我不明白重点在哪里。首先你没有找到“session”,然后你无法访问会话,现在又涉及到一个过滤器的问题。如果你想结束,请提出最后一个问题。我认为你的问题已经得到了回答。当然,正如你所说,会话将稍后由过滤器删除,但你可以获得会话被删除的效果。如果你认为我错了,我道歉。 - malaguna
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接