spring-security: Spring Security 6.x / Single Page Web Application / CSRF - formLogin not working anymore
Describe the bug I have a Spring Boot 3.x application (with Spring Security 6.x). The frontend is Angular 15.2.x. I am following the instructions here to enable CSFR as well as allow post requests from Angular.
While this works, it has the issue if I use the default Spring Security Configuration in Spring Boot (form login) then after successful login I am logged in to the same Login page - ie I cannot access the application.
To Reproduce Create a simple new Spring Boot 3.x application. Configure Security according to here:
[..]
CookieCsrfTokenRepository tokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
XorCsrfTokenRequestAttributeHandler delegate = new XorCsrfTokenRequestAttributeHandler();
// set the name of the attribute the CsrfToken will be populated on
delegate.setCsrfRequestAttributeName("_csrf");
// Use only the handle() method of XorCsrfTokenRequestAttributeHandler and the
// default implementation of resolveCsrfTokenValue() from CsrfTokenRequestHandler
CsrfTokenRequestHandler requestHandler = delegate::handle;
http.authorizeHttpRequests().anyRequest().authenticated().and().formLogin().and().httpBasic().and()
.csrf((csrf) -> csrf
.csrfTokenRepository(tokenRepository)
.csrfTokenRequestHandler(requestHandler)
);
return http.build();
[..]
If you do gradlew bootRun and you try to login then after successful login you are redirected to the login page again. If I do NOT have the additional configuration with CSRF then I can login normally (but then I have the issue to do Post requests in Angular).
Edit: Apparently the /login results in an invalid CSRF token foudn issue when submitting the credentials
Expected behavior After successful login it redirects to my application and not back to /login.
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 20 (6 by maintainers)
@EtienneKaiser, the code
.addFilterAfter(new CsrfCookieFilter(), BasicAuthenticationFilter.class)simply sets the filter order so the custom filter would appear afterBasicAuthenticationFilterin the filter chain. This works even ifBasicAuthenticationFilteris not present. You don’t need to add it for this to work.Please see the Single-Page Applications section of the CSRF chapter of the docs for more information. If you need additional help, please open a question on stackoverflow. This issue is not intended to be a support forum, and I would ask you to try your best not to use it for that purpose.
I am not sure if I can understand your issue correctly. I assume you want to work with a Javascript framework that needs to CRFS token refreshed on every request and has it in its cookies accessible to Javascript for XHR requests. This is an excerpt from working code (it has been according to Spring Boot 3 standards, but maybe not the latest 3.2, but in any case should work.
@jornfranke, I have updated the main CSRF chapter of the reference documentation for the 6.1 release. You can preview it here: https://docs.spring.io/spring-security/reference/6.1-SNAPSHOT/servlet/exploits/csrf.html
Your feedback is most welcome on the updates, and we can keep improving.
In the meantime, I’m going mark as a duplicate of gh-13089 and close this issue for now, as I believe there is no additional work to be done with the docs at this time. If there’s something you feel I’ve missed in the update, or you have specific suggestions for the 5.8 migration guide, let me know and we can re-open or open a new specific issue for it. Thanks!