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?
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.
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.
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.
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.
webClient.mutateWith(csrf()).post()...;
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With