无需数据库/缓存,重启后保持Spring Security会话持久化
Spring Boot 3.2.5中Tomcat会话持久化失效的问题解决
问题根源分析
你的配置无效主要有以下几个原因:
- Spring Security会话对象序列化问题:Tomcat持久化会话时,要求Session中的所有对象必须实现
Serializable接口。虽然Spring Security核心对象(如User、SecurityContextImpl)默认实现了该接口,但如果没有显式配置会话管理,SecurityContext可能未被正确存入Session并完成序列化,导致Tomcat无法持久化会话数据。 - 应用关闭方式不正确:Tomcat的会话持久化仅在正常关闭应用时触发(比如通过
Ctrl+C、Spring Boot Shutdown端点),强制杀死进程会跳过持久化流程,导致sessions文件夹为空。 - 缺少显式的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. 验证配置
- 启动应用,登录
admin用户 - 正常关闭应用,此时
sessions文件夹下会生成类似SESSIONS.ser的文件 - 重新启动应用,访问首页,无需重新登录即可进入
注意事项
- 会话持久化仅适用于正常关闭/重启场景,如果是应用崩溃或强制杀死进程,会话数据仍会丢失
- 默认会话超时时间为30分钟,若登录后超过30分钟再关闭应用,会话已过期,不会被持久化
内容的提问来源于stack exchange,提问作者Rolch2015
相关产品推荐
相关产品推荐

