【问题标题】:How to disable crsf protection in @WebFluxTest?如何在@WebFluxTest 中禁用 csrf 保护?
【发布时间】:2020-03-12 10:11:43
【问题描述】:

为什么我会收到 403 FORBIDDEN 用于以下测试?

@RestController
public class MyServlet {
    @PostMapping("/")
    public Mono<String> accept(Authentication authentication) {}
}


@WebFluxTest(MyServlet.class)
@WithMockUser
public class MyServletTest {
    @Autowired
    private WebTestClient webClient;

    @Test
    public void test() {
        webClient.post().url("/")
            .exchange()
            .expectStatus().isOk();
    }
}

结果:

java.lang.AssertionError: Status expected:<200 OK> but was:<403 FORBIDDEN>

> POST /
> WebTestClient-Request-Id: [1]
> Content-Type: [application/json]

No content

< 403 FORBIDDEN Forbidden
< Content-Type: [text/plain]
< Cache-Control: [no-cache, no-store, max-age=0, must-revalidate]
< Pragma: [no-cache]
< Expires: [0]
< X-Content-Type-Options: [nosniff]
< X-Frame-Options: [DENY]
< X-XSS-Protection: [1 ; mode=block]
< Referrer-Policy: [no-referrer]

CSRF Token has been associated to this client

据我所知,@WebFluxTest 禁用 csrf。那它为什么抱怨呢?

【问题讨论】:

    标签: spring spring-boot spring-security spring-test


    【解决方案1】:
    webClient.mutateWith(csrf()).post()...;
    

    【讨论】:

    • SecurityMockServerConfigurers.csrf()
    【解决方案2】:

    发生这种情况是因为您的类路径中可能有 spring-boot-starter-security。您需要创建一个配置:

    @Configuration
    @EnableWebFluxSecurity
    public class WebFluxSecurityConfig {
      @Bean
      public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        return http.csrf().disable().build();
      }
    }
    

    并将其导入到您的测试中

    @Import(WebFluxSecurityConfig.class)
    

    显然@WebFluxTest中默认不加载SecurityConfig。

    我在这里找到了解决方案:https://github.com/spring-projects/spring-boot/issues/16088

    【讨论】:

    • 啊,谢谢,当我有 @Profile({"local", "test" ... }) 时没有导入配置
    【解决方案3】:

    您可以使用@SpringBootTest@AutoConfigureWebTestClient 加载默认配置,以配置和注入测试客户端。将两个注释都放在您的测试类上。

    【讨论】:

      【解决方案4】:

      造成这种情况的根本原因是你的类路径中有 spring-security 依赖项。

      在我的例子中,它是 Spring Reactive 应用程序,通过创建一个 bean 并使用 @EnableWebFluxSecurity

      对其进行注释来应用安全配置
        @Configuration
         @EnableWebFluxSecurity
         public class SecurityConfig {
         
      @Bean
        public SecurityWebFilterChain securityWebFilterChain(final ServerHttpSecurity http) {
          http.oauth2Client();
          return http.authorizeExchange().anyExchange().permitAll().and().build();
        }
      }
      

      因此,默认情况下 SpringSecurity 配置的性质,CSRF 将被启用。 现在我们必须根据“您需要为您的应用程序启用 CSRF 吗?”问题来决定解决方案 如果答案是肯定的,那么您的测试也应该使用 csrf,这可以由 webClient.mutateWith(csrf()).post() 完成 如果不需要启用 csrf,则通过http.authorizeExchange().anyExchange().permitAll().and().csrf().disable().build();禁用它

      这应该可以帮助您解决问题。

      【讨论】:

        猜你喜欢
        • 2016-01-21
        • 2017-03-19
        • 1970-01-01
        • 2011-03-12
        • 2015-04-22
        • 2010-12-19
        • 1970-01-01
        • 1970-01-01
        • 2012-07-07
        相关资源
        最近更新 更多