-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Closed
Labels
in: webAn issue in web modules (web, webmvc)An issue in web modules (web, webmvc)type: bugA general bugA general bug
Milestone
Description
Describe the bug
Using the new DeferredCsrfToken
, CsrfAuthenticationStrategy
does not regenerate CsrfToken
with CookieCsrfTokenRepository
within the same request. A null
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 the AuthenticationSuccessHandler
below. Related gh-12094.
To Reproduce
See sample.
- Navigate to http://localhost:8080 in the browser and log in with user:password.
- Observe that
POST /login
contains the same token in request and response.
POST /login HTTP/1.1
Host: localhost:8080
...
Cookie: JSESSIONID=EAA9296337F0588BC18C9C1BC0F8DBA1; XSRF-TOKEN=f1f89231-50e7-4eed-a15d-45c184c34e56
HTTP/1.1 200
Set-Cookie: JSESSIONID=5528D2BC31D24431AF4F5A1D61AB0F1A; Path=/; HttpOnly
Set-Cookie: XSRF-TOKEN=; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
X-XSRF-TOKEN: f1f89231-50e7-4eed-a15d-45c184c34e56
...
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
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.csrf((csrf) -> csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
)
.formLogin((formLogin) -> formLogin
.successHandler((request, response, authentication) -> {
CsrfToken csrfToken = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
response.setHeader(csrfToken.getHeaderName(), csrfToken.getToken());
})
);
// @formatter:on
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
// @formatter:off
UserDetails userDetails = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
// @formatter:on
return new InMemoryUserDetailsManager(userDetails);
}
}
Metadata
Metadata
Assignees
Labels
in: webAn issue in web modules (web, webmvc)An issue in web modules (web, webmvc)type: bugA general bugA general bug