\n","author":{"@type":"Person","name":"EricMacau"},"upvoteCount":8,"answerCount":3,"acceptedAnswer":null}}
Reputation: 149
The following SecurityWebFilterChain works very fine in Spring Boot 2.7.x but not working any more in Spring Boot 3.0.0. It just show "An expected CSRF token cannot be found" when calling the REST API in Postman. Would you please to teach me how to solve it?
@Bean
public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) {
http
.cors().disable()
.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint((swe, e) ->
Mono.fromRunnable(() -> swe.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED))
).accessDeniedHandler((swe, e) ->
Mono.fromRunnable(() -> swe.getResponse().setStatusCode(HttpStatus.FORBIDDEN))
)
.and()
.authenticationManager(authenticationManager)
.securityContextRepository(securityContextRepository)
.authorizeExchange(exchange -> exchange
.pathMatchers(HttpMethod.OPTIONS).permitAll()
.pathMatchers("/login", "/register").permitAll()
.anyExchange().authenticated()
.and()
.cors().disable()
.csrf().disable()
)
.formLogin().disable()
.httpBasic().disable()
;
return http.csrf(csrf -> csrf.disable()).build();
}
Upvotes: 8
Views: 8932
Reputation: 324
I experienced the same symptoms when migrating my webflux application to Spring Boot 3.0.0 today, which worked perfectly with 2.7.5. So I googled for "csrf-disabling no longer working" and found this and some few other posts...
However in my case, it was an annotation change of Spring security 6, that caused the problem: @EnableWebFluxSecurity contained "@Configuration" in 5.x version (I checked) - but obviously does no longer and has to be added explicitly.
Thus the complete SecurityWebFilterChain bean was not found after migrating... Now the working code looks as follows:
@EnableWebFluxSecurity
@Configuration // <- this was integrated in @EnableWebFluxSecurity with Spring Security 5.x
public class AccountWebSecurityConfig {
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http,
ReactiveAuthenticationManager authenticationManager,
ServerAccessDeniedHandler accessDeniedHandler,
ServerAuthenticationEntryPoint authenticationEntryPoint) {
http.csrf().disable()
.httpBasic(httpBasicSpec -> httpBasicSpec
.authenticationManager(authenticationManager)
// when moving next line to exceptionHandlingSpecs, get empty body 401 for authentication failures (e.g. Invalid Credentials)
.authenticationEntryPoint(authenticationEntryPoint)
)
.authorizeExchange()
//...
}
As your FilterChain - snippet does not show the annotations at your class, chances are, you may also missing the @Configuration
In my case now everything works as before :-)
Upvotes: 13
Reputation: 12909
You forgot to enable resource-server in your filter-chain:
http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(authenticationConverter)
You need a custom authentication converter, as done above, mostly for roles mapping.
Detailed tutorials (for servlets) here: https://github.com/ch4mpy/spring-addons/tree/master/samples/tutorials. You might then refer to samples for reactive apps.
Upvotes: 0
Reputation: 74
You can try it out
https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/jwt.html
application.yml
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://idp.example.com/issuer
Upvotes: 0