I'm using Spring Webflux, Security, Session and Redis. It seems that once the 'csrfTokenRepository' is set in a security configuration like the one below, the SESSION
cookie is no longer set as part of normal responses. The scenario at play is one where a SPA is using Basic Authentication and subsequently setting X-XSRF-TOKEN
and X-Auth-Token
for future AJAX calls.
Please note that a XSRF-TOKEN
cookie is set correctly after subscribing to a Mono<CsrfToken>
. The only issue at hand is that, under the given scenario, no SESSION
cookie is being set which is unexpected.
@Bean
fun webHttpSecurity(http: ServerHttpSecurity): SecurityWebFilterChain {
return http {
securityMatcher(PathPatternParserServerWebExchangeMatcher("/web/**"))
httpBasic { }
authorizeExchange {
authorize("/web/login", permitAll)
authorize(anyExchange, authenticated)
}
csrf {
csrfTokenRepository = CookieServerCsrfTokenRepository.withHttpOnlyFalse()
}
}
}
If we comment out setting the csrfTokenRepository
as shown below, a SESSION
cookie is set, as expected. This behavior happens across multiple version of Spring Boot including 2.7.4.
@Bean
fun webHttpSecurity(http: ServerHttpSecurity): SecurityWebFilterChain {
return http {
securityMatcher(PathPatternParserServerWebExchangeMatcher("/web/**"))
httpBasic { }
authorizeExchange {
authorize("/web/login", permitAll)
authorize(anyExchange, authenticated)
}
csrf {
// csrfTokenRepository = CookieServerCsrfTokenRepository.withHttpOnlyFalse()
}
}
}
The default CSRF token repositories are session based. This means that they will create a new instance of a session as necessary. When this happens, a cookie is set because a session instance has been create.
The moment the default CSRF token is swapped with a CookieServerCsrfTokenRepository, session are no longer created by default and therefore no session cookies are set.
The key insight here is that the default CSRF repositories are session based and the CookieServerCsrfTokenRepository is void of session behavior.