spring-bootspring-securityspring-security-rest

Different authentication on GET and POST


I've been following a spring security example but I cannot make sense of it. A simple RestController replying hello on a GetMapping("/hello") with a 200 status code. Once I change it to a PostMapping I receive a 401 for the same credentials sent.

Seems I am missing something fundamental here as I would expect both requests to return a 200 status code.

The security config:

@Configuration
public class ProjectConfig extends WebSecurityConfigurerAdapter {

    @Override
    @Bean
    public UserDetailsService userDetailsService() {
        return new InMemoryUserDetailsManager(
                List.of(
                        User.withUsername("john")
                                .password("12345")
                                .authorities("ROLE_ADMIN")
                                .build(),
                        User.withUsername("jane")
                                .password("12345")
                                .authorities("ROLE_MANAGER")
                                .build()
                )
        );
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic()
                .and()
                .authorizeRequests()
                .anyRequest()
                .hasRole("ADMIN");
    }
}

The RestController with the following get mapping returns 200 for this call:

curl -v -u john:12345 localhost:8080/hello

and this mapping:

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello!";
    }
}

The RestController with the following post mapping returns 401 for this call:

curl -X POST -v -u john:12345 localhost:8080/hello

and this mapping:

@RestController
public class HelloController {

    @PostMapping("/hello")
    public String hello() {
        return "Hello!";
    }
}

Solution

  • Spring's CSRF protection comes enabled by default in Spring Security. POST requests are affected by this behavior.

    Disable it by doing:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
    }