Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable crsf protection in @WebFluxTest?

Why am I receiving a 403 FORBIDDEN for the following test?

@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();
    }
}

Result:

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

As far as I know, @WebFluxTest disables csrf. So why is it complaining?

like image 313
membersound Avatar asked Mar 12 '20 10:03

membersound


People also ask

How do I disable CSRF?

You can disable CSRF protection by setting the csrf. protection. enabled system configuration item to the value false. This can be done via REST API.

When should I disable CSRF protection?

Our recommendation is to use CSRF protection for any request that could be processed by a browser by normal users. If you are only creating a service that is used by non-browser clients, you will likely want to disable CSRF protection.

Why should we disable CSRF?

It is an attack that forces an end user to execute unwanted actions on a web application in which they are currently authenticated. CSRF attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request.

Is CSRF enabled by default?

CSRF protection is enabled by default. However, it is simple to disable CSRF protection if it makes sense for your application. The XML configuration below will disable CSRF protection.


2 Answers

webClient.mutateWith(csrf()).post()...;
like image 64
membersound Avatar answered Sep 21 '22 02:09

membersound


This is happening because you probably have spring-boot-starter-security in your classpath. You need to create a config:

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

and import it into your test with

@Import(WebFluxSecurityConfig.class)

Apparently the SecurityConfig is not loaded by default in @WebFluxTest.

I found the solution here: https://github.com/spring-projects/spring-boot/issues/16088

like image 37
tomasulo Avatar answered Sep 21 '22 02:09

tomasulo