Spring Security 6 OAuth2资源服务器已认证会话配置疑问
解决方案
要实现客户端每会话仅认证一次,核心是修改Spring Security的会话创建策略,并确保认证信息被持久化到会话中,具体配置如下:
1. 调整SecurityFilterChain配置
修改过滤器链配置,显式设置会话创建策略为IF_NEEDED,并确保SecurityContext通过会话存储:
@Bean public SecurityFilterChain oauth2Chain(HttpSecurity http) throws Exception { http // 配置会话创建策略:认证成功后自动创建会话 .sessionManagement(session -> session .sessionCreationPolicy(SessionCreationPolicy.IF_NEEDED)) // 将认证信息存储到HttpSession中 .securityContext(securityContext -> securityContext .securityContextRepository(new HttpSessionSecurityContextRepository())) // 所有请求需认证 .authorizeHttpRequests(authorize -> authorize .anyRequest().authenticated()) // 保留原JWT资源服务器验证配置 .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())); return http.build(); }
关键配置说明
SessionCreationPolicy.IF_NEEDED:默认情况下OAuth2资源服务器采用STATELESS(无状态)策略,不会创建会话。改为IF_NEEDED后,服务器会在JWT验证成功后自动创建会话,并将认证信息存入其中。HttpSessionSecurityContextRepository:负责将包含认证信息的SecurityContext持久化到HttpSession,后续请求携带会话Cookie时,服务器直接从会话读取认证信息,无需重复验证JWT。
2. 保留会话存储配置
你当前的HtmlSessionConfig配置无需修改,内存会话存储适合测试场景:
@EnableSpringHttpSession @Configuration public class HtmlSessionConfig { @Bean public MapSessionRepository sessionRepository() { return new MapSessionRepository(new ConcurrentHashMap<>()); } }
验证流程
- 客户端首次请求携带JWT,服务器验证通过后创建会话,返回含会话ID的Cookie。
- 客户端后续请求仅需携带该会话Cookie,服务器直接从会话读取认证信息完成校验,直到会话过期。
内容的提问来源于stack exchange,提问作者PaoloJ42
相关产品推荐
相关产品推荐

