You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security 6:如何强制失效非当前用户的Session?

解决Spring Boot 3/Spring Security 6中强制失效用户会话的问题

核心原因

调用SessionInformation.expireNow()仅会将会话标记为过期状态,不会直接触发会话销毁操作。只有当Spring Security的ConcurrentSessionFilter检测到该过期状态时,才会执行会话失效、用户登出的逻辑。如果你的配置中缺少该过滤器或相关配置不完整,就会出现调用方法后会话仍有效的情况。

完整解决方案步骤

1. 完善SecurityFilterChain配置,启用ConcurrentSessionFilter

需要在会话管理配置中添加并发会话控制,Spring Security会自动注册ConcurrentSessionFilter来处理过期会话:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http, SessionRegistry sessionRegistry) throws Exception {
    http
        // 其他原有配置...
        .sessionManagement(session -> session
            .maximumSessions(1) // 根据业务需求设置允许的最大并发会话数
            .sessionRegistry(sessionRegistry)
            .and()
            .sessionAuthenticationStrategy(new RegisterSessionAuthenticationStrategy(sessionRegistry))
        )
        // 其他原有配置...
    return http.build();
}

说明:maximumSessions()方法会自动引入ConcurrentSessionFilter,该过滤器会在每次请求时检查当前会话是否被标记为过期,若已过期则立即执行会话失效、用户登出操作。

2. 实现强制登出的业务逻辑

获取目标用户的会话信息后,先标记会话为过期,再手动销毁对应的HttpSession以加速失效:

@Autowired
private SessionRegistry sessionRegistry;

public void forceLogoutUser(String username) {
    // 筛选目标用户的身份信息
    List<Object> targetPrincipals = sessionRegistry.getAllPrincipals()
        .stream()
        .filter(principal -> ((User) principal).getUsername().equals(username))
        .toList();
    
    for (Object principal : targetPrincipals) {
        // 获取该用户的所有有效会话
        List<SessionInformation> userSessions = sessionRegistry.getAllSessions(principal, false);
        for (SessionInformation sessionInfo : userSessions) {
            // 标记会话为过期
            sessionInfo.expireNow();
            // 手动销毁HttpSession(加速会话失效)
            try {
                HttpSession session = sessionInfo.getSession();
                if (session != null) {
                    session.invalidate();
                }
            } catch (Exception e) {
                // 处理会话已销毁等异常情况
            }
        }
    }
}

3. 验证配置有效性

  • 确保HttpSessionEventPublisher已正确注册(你已完成该配置),它会在会话销毁时通知SessionRegistry移除对应会话信息。
  • 测试时,目标用户调用强制登出后,新发起的请求会被拦截并跳转至登录页(或返回未授权响应);正在处理中的请求需等完成后才会失效,属于正常现象。

关键概念补充

会话有三种状态:活跃、过期、已销毁。通过session.invalidate()或Servlet容器管理失效的会话视为“已销毁”;而“过期”会话是Spring Security因某些原因(通常是达到用户最大会话数时移除最近最少使用的会话)想要终止的会话,会尽快通过Filter移除。

内容的提问来源于stack exchange,提问作者Lachezar Balev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 18:00:17