Spring Security blocks POST requests despite settings

Asked

Viewed 1,050 times

3

I am developing a REST API based on Spring Boot (spring-boot-starter-web) where I use Spring Security (spring-security-core and spring-security-config) to configure the protection of different endpoints.

Authentication is done on the basis of a local database where users with two types of roles different: ADMIN and USER. The USER should be able to do GET all points of the API and POST to endpoints on the basis of routeA. The ADMIN should be able to do the same as USER and still do POST and DELETE to endpoints on the basis of routeB.

But the behavior I’m having is that I can do GET to any endpoint but POST results in HTTP 403 Forbidden or with users who have the role ADMIN whether USER, that is not expected based on my SecurityConfiguration.

Any idea what I’m missing?


Securityconfiguration.java

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

Routebcontroller . java

@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!";
    }

}

Restauthenticationentrypoint.java

@Component
public class RESTAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {

    @Override
    public void afterPropertiesSet() throws Exception {
        setRealmName("AppNameHere");
        super.afterPropertiesSet();
    }
}
  • 1

    Try to disable the CSRF.

  • Thank you @Statelessdev, this really did not make it back 403! Either way both the user USER as ADMIN now they can do POST. Any idea?

  • But that’s supposed to be your application, right? Or do you mean route B?

  • To the RouteA both should be able to do POST, already to the RouteB only users with an administrator role should be able to

  • The problem was the expression I was using on antmatcher(HttpMethod, String) that should be /routeB/** instead of /routeB/*. @Statelessdev please answer the question so I can mark your help as an answer :)

  • Created response.

Show 1 more comment

1 answer

1


You must disable the CSRF:

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.