singe3
singe3

Reputation: 2105

Deny access to some inherited controller methods

I have a base REST controller that provides general methods (GET, PUT, POST, DELETE).

Then specific controllers inherit these methods and either use them or override them. When such a subclass controller override an inherited controller method, I sometimes needs to add for example @PreAuthorize("hasAnyRole('ROLE_ADMIN')") to restrict the access to some security roles.

However, now I have another subclass controller for which I need to allow access only to the GET inherited methods. All other inherited methods (PUT, POST, DELETE) should be forbidden to absolutely everyone.

I tried to Override the DELETE with an empty @PreAuthorize:

    @PreAuthorize
    @Override
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    @ResponseStatus(HttpStatus.NO_CONTENT)
    @ResponseBody
    public void removeResource(@PathVariable("id") final Long id, final Principal principal) throws UnknownResourceException {
        // Deny access to everyone
    }

However, with no value, it's not a valid annotation.

Is there a usual pattern to solve this issue ?

Upvotes: 1

Views: 467

Answers (1)

sven.kwiotek
sven.kwiotek

Reputation: 1479

Spring recommends to secure your Mapping Handler with HttpSecurity:

In practice we recommend that you use method security at your service layer, to control access to your application, and do not rely entirely on the use of security constraints defined at the web-application level. URLs change and it is difficult to take account of all the possible URLs that an application might support and how requests might be manipulated. You should try and restrict yourself to using a few simple ant paths which are simple to understand. Always try to use a"deny-by-default" approach where you have a catch-all wildcard ( /** or **) defined last and denying access.

So for example it is secured using URL security and can be differentiate by Http method:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    // ...
    @Override
    protected void configure(HttpSecurity http) throws Exception {
       http
          .httpBasic().and()
          .authorizeRequests()
            .antMatchers(HttpMethod.POST, "/myurl").hasRole("ADMIN")
            .antMatchers(HttpMethod.GET, "/myurl/**").hasRole("USER")
            .antMatchers(HttpMethod.DELETE, "/myurl/**").hasRole("ADMIN")
            .antMatchers(HttpMethod.PUT, "/myurl/**").hasRole("USER");
    }
    // ...
}

Upvotes: 1

Related Questions