Shorn
Shorn

Reputation: 21456

Spring security: How to make annotation based role specifications have precedence over pattern-based role specifications

I want to combine role-based annotations and pattern-based authorization configuration.

I want the the pattern-based authorization to be the "fallback in case no annotation is specified".

An example of an annotated method endpoint:

@PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
@RequestMapping(
  method = RequestMethod.POST,
  headers = "Accept=application/json",
  path="publicApi/doWork" )
public void doWork() {
  ...
}

And my pattern-based authorization configuration looks like:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
// specifies actuator endpoints should be secured by this config
@Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  private void configureEndpointRoles(HttpSecurity http) throws Exception {
    http.authorizeRequests().
      antMatchers(anonymousUrlPatterns()).permitAll().
      antMatchers("/publicApi/**").access("hasAnyRole('ROLE_ADMIN')").
      anyRequest().denyAll();
    ;
  }
}

Here's how I want the to work:

How would I go about defining this behaviour?

With the above setup as specified, the pattern-based configuration takes precedence and the endpoint invocation is denied (I'm not sure if the pattern-based configuration is taking precedence or if Spring is combining them somehow?)

Spring version - 4.2.3


Update: I've tried updating the EnableGlobalMethodSecurity to:

@EnableGlobalMethodSecurity(
  prePostEnabled = true,
  order = Ordered.HIGHEST_PRECEDENCE)

But that didn't seem to change the behaviour.

Upvotes: 3

Views: 494

Answers (1)

Shorn
Shorn

Reputation: 21456

As per comment from @dur, it looks like you can't do this with a basic configuration.

Under the default Spring Security AccessDecisionManager strategy, the "No" vote from the pattern-based rule will cause the overall invocation to be denied.

It looks like the behaviour I want will involve writing some custom decision manager logic, something like: http://www.baeldung.com/spring-security-custom-voter

Upvotes: 2

Related Questions