Categories
java spring spring-security

Spring Security’s @PreAuthorize on type level can not be overridden on method level

I’m trying to protect a Controller with the @PreAuthorize annotation at type level and try to override that behavior by annotating some methods with a different @PreAuthorize. The Problem is however, that Spring is evaluating the method annotation first (grants access) and is then evaluating the class annotation (denies access).

Is there any way to reverse that order? I couldn’t figure it out yet.

Edit:

On the method level, I want to grant access to non-registered Users only:

@PreAuthorize("isAnonymous()")
@RequestMapping(value = "/create", method = RequestMethod.GET)
public String renderCreateEntity(ModelMap model) {
return userService.renderCreateEntity(model);
}

The standard for this Controller however, should be to allow fully authenticated users only:

@Controller
@RequestMapping(value = "/user")
@PreAuthorize("isFullyAuthenticated()")
public class UserController { [...] }

When debug-stepping through the app, I see that isAnonymous() is evaluated first and then isFullyAuthenticated() thus resulting in an grant of access right and immediately denying access again.

Thanks for all your replys.
The answer however, was something totally different 🙂

I put this here in case anyone else has the same problems.

I registered a custom validator in an @InitBinder annotated method. This binding method is called AFTER the method call requested on the controller. And since this binding method was not annotated with @PreAuthorize, the request was denied.

The solution was to annotate the binding method like this:

@InitBinder
@PreAuthorize("permitAll")
public void initBinder(WebDataBinder binder) {
binder.setValidator(validator);
}

And then, the method calls from my OP evaluated like expected.