Spring Boot 3.0 + Security 6 +WebFlux 导致 Postman 中“找不到预期的 CSRF 令牌”

Eri*_*cau 7 csrf spring-security spring-boot

以下SecurityWebFilterChain在 Spring Boot 2.7.x 中工作得很好,但在 Spring Boot 3.0.0 中不再工作。在Postman中调用REST API时,它只是显示“无法找到预期的CSRF令牌”。请您教我如何解决它?

@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();
}
Run Code Online (Sandbox Code Playgroud)

邮递员屏幕截图

Jür*_*hen 12

我今天将 webflux 应用程序迁移到 Spring Boot 3.0.0 时遇到了同样的症状,它与 2.7.5 完美配合。所以我在谷歌上搜索“csrf-disabling不再起作用”并发现了这个和其他一些帖子......

然而,就我而言,是 Spring security 6 的注释更改导致了问题: @EnableWebFluxSecurity 在 5.x 版本中包含“@Configuration”(我检查过) - 但显然不再包含,必须显式添加。

因此,迁移后找不到完整的 SecurityWebFilterChain bean...现在工作代码如下所示:

@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()
        //...
}
Run Code Online (Sandbox Code Playgroud)

由于您的 FilterChain - 代码片段没有在您的类中显示注释,因此您可能还缺少 @Configuration

就我而言,现在一切都像以前一样工作:-)


Min*_*rần 0

你可以尝试一下

https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/jwt.html

应用程序.yml

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://idp.example.com/issuer
Run Code Online (Sandbox Code Playgroud)