I have a Spring Boot web application, where most endpoints require authentication. However, a few mappings shall allow anonymous access; they are exceptions from the general rule.
I cannot get this to work for POST calls, they are always getting 403.
The security configuration...
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().regexMatchers("/", "/posthello").anonymous()
.and()
.authorizeRequests().anyRequest().authenticated();
}
}
The controller...
@RestController
public class HelloController {
// This returns HTTP 200 and body on anonymous calls
@GetMapping("/")
public String helloWorld() {
return "Hello World!";
}
// This demands authentication, as expected
@GetMapping("/gethello")
public String getHelloWorld(String body) {
return "You got: Hello, World!";
}
// This always returns HTTP 403 on anonymous calls,
// even though it is supposed to be excepted
@PostMapping("/posthello")
public String postHelloWorld(@RequestBody String body) {
return "You posted: " + body;
}
}
Patel Romil is correct that the 403 is caused by CSRF and that disabling CSRF would disable that protection. He's also wise to warn against doing that in a production application.
An alternative to disabling CSRF for the entire site is specifying an allowlist of endpoints, like so:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.ignoringAntMatchers("/posthello")
.and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/posthello").anonymous()
.anyRequest().authenticated();
}
}
That said, the real solution is likely to configure the application to use CSRF tokens. Without CSRF protection, arbitrary third-party web applications can invoke POST /posthello.
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