Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 889
chzbrgla Avatar asked Oct 03 '11 12:10

chzbrgla


People also ask

Which annotation can be used with Spring Security to apply method level security?

Method-level security is implemented by placing the @PreAuthorize annotation on controller methods (actually one of a set of annotations available, but the most commonly used). This annotation contains a Spring Expression Language (SpEL) snippet that is assessed to determine if the request should be authenticated.

How does @PreAuthorize work in spring boot?

Spring Security provides method level security using @PreAuthorize and @PostAuthorize annotations. This is expression-based access control. The @PreAuthorize can check for authorization before entering into method. The @PreAuthorize authorizes on the basis of role or the argument which is passed to the method.

What's the difference between @secured and @PreAuthorize in Spring Security?

The difference between @Secured and @PreAuthorize are as follows : The main difference between @Secured and @PreAuthorize is that @PreAuthorize can work with Spring EL. We can access methods and properties of SecurityExpressionRoot while using @PreAuthorize but not with @Secured.

How does Spring Security Hasrole work?

By default, Spring Security uses a thread-local copy of this class. This means each request in our application has its security context that contains details of the user making the request. To use it, we simply call the static methods in SecurityContextHolder: Authentication auth = SecurityContextHolder.


1 Answers

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.

like image 82
chzbrgla Avatar answered Nov 15 '22 18:11

chzbrgla