配置CookieServerCsrfTokenRepository后SESSION Cookie未设置问题求助
问题现象
使用Spring Webflux、Security、Session结合Redis时,在安全配置中设置csrfTokenRepository = CookieServerCsrfTokenRepository.withHttpOnlyFalse()后,响应不再携带SESSION Cookie;注释掉该配置后,SESSION Cookie生成正常。当前场景为SPA应用使用Basic Authentication,后续AJAX请求需要携带X-XSRF-TOKEN和X-Auth-Token,目前订阅Mono<CsrfToken>后XSRF-TOKEN Cookie能正常设置,仅SESSION Cookie未生成。
原因解析
当自定义CsrfTokenRepository时,Spring Security WebFlux默认的Session初始化触发逻辑被改变。默认情况下,Csrf过滤器会依赖Session存储Csrf Token,但切换到Cookie存储Csrf Token后,框架不会自动触发Session的创建流程,而Session Cookie的生成需要Session被主动初始化。
解决方案
方案1:显式配置Session管理,强制初始化Session
在Security配置中添加sessionManagement配置,指定会话创建策略为ALWAYS,确保请求触发Session初始化:
@Bean fun webHttpSecurity(http: ServerHttpSecurity): SecurityWebFilterChain { return http { securityMatcher(PathPatternParserServerWebExchangeMatcher("/web/**")) httpBasic { } authorizeExchange { authorize("/web/login", permitAll) authorize(anyExchange, authenticated) } csrf { csrfTokenRepository = CookieServerCsrfTokenRepository.withHttpOnlyFalse() } sessionManagement { sessionCreationPolicy = SessionCreationPolicy.ALWAYS } } }
方案2:在登录接口主动触发Session创建
如果不想全局强制创建Session,可以在/web/login接口的处理逻辑中主动订阅Mono<WebSession>,触发Session初始化:
@GetMapping("/web/login") fun login(exchange: ServerWebExchange): Mono<ResponseEntity<Void>> { // 主动触发Session创建 return exchange.session .map { session -> // 可在此处添加其他登录相关逻辑 ResponseEntity.ok().build() } }
验证说明
修改配置后,发起登录请求或其他授权请求时,响应头中会同时携带SESSION Cookie和XSRF-TOKEN Cookie,满足SPA后续AJAX请求的携带需求。
内容的提问来源于stack exchange,提问作者Newbie

