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();
}
}
Try to disable the CSRF.
– StatelessDev
Thank you @Statelessdev, this really did not make it back
403
! Either way both the userUSER
asADMIN
now they can doPOST
. Any idea?– Tiago Leite
But that’s supposed to be your application, right? Or do you mean route B?
– StatelessDev
To the
RouteA
both should be able to doPOST
, already to theRouteB
only users with an administrator role should be able to– Tiago Leite
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 :)– Tiago Leite
Created response.
– StatelessDev