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

无需数据库/缓存,重启后保持Spring Security会话持久化

Spring Boot 3.2.5中Tomcat会话持久化失效的问题解决

问题根源分析

你的配置无效主要有以下几个原因:

  1. Spring Security会话对象序列化问题:Tomcat持久化会话时,要求Session中的所有对象必须实现Serializable接口。虽然Spring Security核心对象(如User、SecurityContextImpl)默认实现了该接口,但如果没有显式配置会话管理,SecurityContext可能未被正确存入Session并完成序列化,导致Tomcat无法持久化会话数据。
  2. 应用关闭方式不正确:Tomcat的会话持久化仅在正常关闭应用时触发(比如通过Ctrl+C、Spring Boot Shutdown端点),强制杀死进程会跳过持久化流程,导致sessions文件夹为空。
  3. 缺少显式的Spring Security会话配置:仅靠server.servlet.session.persistent=true不足以让Spring Security配合Tomcat完成会话持久化,需要明确配置会话管理策略。

具体解决步骤

1. 添加完整的Spring Security配置

创建包含会话管理的SecurityFilterChain配置,确保会话被正确处理:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // 配置所有请求需要认证
            .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
            // 启用默认表单登录
            .formLogin(form -> form.permitAll())
            // 配置会话管理
            .sessionManagement(session -> session
                // 仅在需要时创建会话(默认策略,显式声明更清晰)
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                // 限制同一用户只能有一个会话
                .maximumSessions(1)
            );
        return http.build();
    }

    @Bean
    public UserDetailsService users() {
        UserDetails admin = User.withDefaultPasswordEncoder()
            .username("admin")
            .password("password")
            .roles("USER", "ADMIN")
            .build();
        return new InMemoryUserDetailsManager(admin);
    }
}

2. 确保正常关闭应用

测试时不要强制杀死进程,使用以下方式关闭:

  • 在终端按Ctrl+C
  • 调用Spring Boot的Shutdown端点(需先启用:management.endpoints.web.exposure.include=shutdown,然后POST请求/actuator/shutdown)

3. 可选:自定义Tomcat会话管理器配置

如果上述配置仍不生效,可以显式配置Tomcat的StandardManager确保持久化:

@Configuration
public class TomcatSessionConfig implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        factory.addContextCustomizers(context -> {
            StandardManager manager = new StandardManager();
            // 指定会话存储目录,对应application.properties中的配置
            manager.setPathname("sessions");
            // 启用会话持久化
            manager.setPersistent(true);
            context.setManager(manager);
        });
    }
}

4. 验证配置

  1. 启动应用,登录admin用户
  2. 正常关闭应用,此时sessions文件夹下会生成类似SESSIONS.ser的文件
  3. 重新启动应用,访问首页,无需重新登录即可进入

注意事项

  • 会话持久化仅适用于正常关闭/重启场景,如果是应用崩溃或强制杀死进程,会话数据仍会丢失
  • 默认会话超时时间为30分钟,若登录后超过30分钟再关闭应用,会话已过期,不会被持久化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 22:07:49