-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CsrfAuthenticationStrategy does not regenerate CsrfToken with CookieCsrfTokenRepository #12141
Comments
@sjohnr I noticed a similar issue when trying to upgrade JHipster to use Spring Boot 3 and Spring Security 6. It seems that an XSRF-TOKEN cookie is not returned after an oauth2 login to Keycloak. With Spring Boot 2.x, a cookie is returned. jhipster/generator-jhipster#19791 (comment) I tried the workaround suggested here: .oauth2Login(login -> login
.successHandler((request, response, authentication) -> {
CsrfToken csrfToken = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
response.setHeader(csrfToken.getHeaderName(), csrfToken.getToken());
})
) However, this causes the redirect back to the originating URL to not happen. It just stalls at:
Is it possible to configure the success handler so it calls the default one after adding the cookie? |
The following seems to work. Not sure if it's the best solution: .oauth2Login(login -> login
.successHandler((request, response, authentication) -> {
CsrfToken csrfToken = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
response.setHeader(csrfToken.getHeaderName(), csrfToken.getToken());
SavedRequestAwareAuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler();
handler.onAuthenticationSuccess(request, response, authentication);
})
) |
Hi @mraible! Yes, your workaround is a fine approach. See this comment for some additional context as well. Actually, @jzheaux and I were just working through some issues with The other thing you might try is to actually add a Here's an example on the servlet side: @Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// ...
.oauth2Login(Customizer.withDefaults())
.addFilterAfter(new CsrfCookieFilter(), BasicAuthenticationFilter.class);
return http.build();
}
private static final class CsrfCookieFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrfToken = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
response.setHeader(csrfToken.getHeaderName(), csrfToken.getToken());
filterChain.doFilter(request, response);
}
} Note: The placement of the filter is not exact, but after |
@sjohnr I can confirm that your suggested solution works. Thank you! It seems strange that Spring Security's WebFlux support ships with a .csrf(csrf -> csrf
.csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse())
// See https://stackoverflow.com/q/74447118/65681
.csrfTokenRequestHandler(new ServerCsrfTokenRequestAttributeHandler()))
// See https://github.com/spring-projects/spring-security/issues/5766
.addFilterAt(new CookieCsrfFilter(), SecurityWebFiltersOrder.REACTOR_CONTEXT) |
Thanks for the feedback @mraible!
I'm not sure I understand your comment. I can't find such a class in Spring Security. Perhaps it was added in your project for a very similar reason? |
@sjohnr You are correct. The |
The solutioin to add the custom CsrfCookieFilter works. I was hoping that Spring Boot engineer can consider providing a built-in CsrfCookieFilter for us. In fact, just provide an argument to the method call , something such as shown below, to automatically add a built-in CsrfCookieFilter for us, if the argument is true. .csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse() ,true) |
Describe the bug
Using the new
DeferredCsrfToken
,CsrfAuthenticationStrategy
does not regenerateCsrfToken
withCookieCsrfTokenRepository
within the same request. Anull
token cookie is added, but it does not generate a new one.Note: In 6.0, eagerly loading the token is no longer the default, and requires accessing the request attribute (
request.getAttribute(CsrfToken.class.getName())
) manually as in theAuthenticationSuccessHandler
below. Related gh-12094.To Reproduce
See sample.
POST /login
contains the same token in request and response.Expected behavior
When eagerly regenerating the
CsrfToken
, the cookie (and header in this example) should reflect the updated token after a successful login.Sample
Spring Security Version: 5.8.0-RC1
The text was updated successfully, but these errors were encountered: