Spring Security blocks POST requests despite SecurityConfig : <p>I'm developing a REST API based on Spring Boot (<code>spring-boot-starter-web</code>) where I use Spring Security (<code>spring-security-core</code> e <code>spring-security-config</code>) to protect the different endpoints.</p>

<p>The authentication is done by using a local database that contains  users with two different sets of roles: <code>ADMIN</code> and<code>USER</code>. <code>USER</code> should be able to<code>GET</code> all API endpoints and <code>POST</code> to endpoints based on<code>routeA</code>. <code>ADMIN</code> should be able to do the same as<code>USER</code> plus <code>POST</code> and<code>DELETE</code> to endpoints based on `routeB</p>

<p>However the behavior I'm getting is that I can do <code>GET</code> requests to any endpoint but <code>POST</code> requests always return <code>HTTP 403 Forbidden</code> for either type of user - <code>ADMIN</code> and <code>USER</code> - which is not expected what I'm expecting based on my <code>SecurityConfiguration</code>.</p>

<p>Any ideas of what am I missing?</p>

<hr>

<p><strong>SecurityConfiguration.java</strong>
</p>

<pre><code>@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private static final Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class);

    @Autowired
    private RESTAuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    private DataSource dataSource;

    @Override
    public void configure(AuthenticationManagerBuilder builder) throws Exception {
        logger.info("Using database as the authentication provider.");
        builder.jdbcAuthentication().dataSource(dataSource).passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().
            authorizeRequests().antMatchers(HttpMethod.GET, "/**").hasAnyRole("ADMIN", "USER")
                               .antMatchers(HttpMethod.POST, "/routeA/*").hasAnyRole("ADMIN", "USER")
                               .antMatchers(HttpMethod.POST, "/routeB/*").hasRole("ADMIN")
                               .antMatchers(HttpMethod.DELETE, "/routeB/*").hasRole("ADMIN").and().
            requestCache().requestCache(new NullRequestCache()).and().
            httpBasic().authenticationEntryPoint(authenticationEntryPoint).and().
            cors();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH"));
        configuration.setAllowCredentials(true);
        configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
</code></pre>

<p><strong>RouteBController .java</strong>
</p>

<pre><code>@RestController
public class RouteBController {

    static final Logger logger = LoggerFactory.getLogger(RouteBController.class);

    public RouteBController() { }

    @RequestMapping(value = "routeB", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.GET)
    public String getStuff() {
        return "Got a hello world!";
    }

    @RequestMapping(value = "routeB", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)
    public String postStuff() {
        return "Posted a hello world!";
    }

}
</code></pre>

<p><strong>RESTAuthenticationEntryPoint.java</strong>
</p>

<pre><code>@Component
public class RESTAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {

    @Override
    public void afterPropertiesSet() throws Exception {
        setRealmName("AppNameHere");
        super.afterPropertiesSet();
    }
}
</code></pre>
