如何同时启用CookieCsrfTokenRepository.withHttpOnlyFalse()与@EnableJdbcHttpSession?
问题解答
可以同时使用@EnableJdbcHttpSession和CookieCsrfTokenRepository,二者职责不冲突,你遇到的问题大概率是配置细节或Spring Session初始化环节的问题,以下是具体分析和解决方案:
问题根源
@EnableJdbcHttpSession的作用是替换Spring默认的HttpSession实现,将会话数据持久化到数据库;而CookieCsrfTokenRepository是把CSRF Token存储在Cookie中供前端读取,二者功能独立、完全可以共存。你碰到的异常可能来自这几个点:
- Spring Session的数据源或表结构未正确配置,导致会话无法创建,进而无法生成
SESSIONCookie - CSRF配置的细节缺失,导致Token处理逻辑异常
- 对会话创建时机的误解(默认登录成功后才会生成会话)
解决方案
1. 确保Spring Session配置正确
如果应用存在多个数据源,需要显式指定Spring Session使用的数据源;同时确保Spring Session所需的表已初始化:
@Bean public JdbcHttpSessionConfiguration jdbcHttpSessionConfiguration(DataSource dataSource) { JdbcHttpSessionConfiguration config = new JdbcHttpSessionConfiguration(); config.setDataSource(dataSource); return config; }
在配置文件中添加自动建表配置:
spring.session.jdbc.initialize-schema=always spring.session.jdbc.table-name=spring_session # 可选,默认表名即为该值
2. 修正SecurityFilterChain配置
调整CSRF和会话管理的配置细节,确保逻辑正确:
@Configuration @EnableJdbcHttpSession public class SecurityConfiguration { @Bean public JdbcHttpSessionConfiguration jdbcHttpSessionConfiguration(DataSource dataSource) { JdbcHttpSessionConfiguration config = new JdbcHttpSessionConfiguration(); config.setDataSource(dataSource); return config; } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated()) .formLogin(withDefaults()) // 明确会话创建策略:仅在需要时创建(登录成功后自动触发) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)) .csrf(csrf -> csrf // 配置CSRF Token存储到Cookie,允许前端JS读取 .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) // 配置默认Token解析器,适配AngularJS的X-XSRF-TOKEN请求头逻辑 .csrfTokenRequestHandler(new XorCsrfTokenRequestAttributeHandler()) ); return http.build(); } }
3. 验证逻辑
- 访问登录页:检查浏览器Cookie中是否存在
XSRF-TOKEN(由CookieCsrfTokenRepository生成) - 登录成功后:检查是否出现
SESSIONCookie(由Spring Session JDBC生成) - 发送POST请求时:确保请求头携带
X-XSRF-TOKEN,值与XSRF-TOKENCookie一致
关键说明
@EnableJdbcHttpSession不会覆盖你显式配置的csrfTokenRepository,只要在SecurityFilterChain中明确指定,就会优先使用CookieCsrfTokenRepositorySESSIONCookie只有在HttpSession被创建时才会生成,默认Spring Security在登录成功后创建会话,所以登录前不会出现该Cookie,属于正常现象
内容的提问来源于stack exchange,提问作者Assaf A
相关产品推荐
相关产品推荐

