I have several REST APIs.
I would like to put Security on top of all of them, in order to allowed the functionalities only for certain roles.
I put the @EnableGlobalMethodSecurity(prePostEnabled = true) in the configuration class.
I have a DB with a table which stores the roles.
@RequestMapping(path = "/error", method = RequestMethod.GET)
@PreAuthorize("hasRole('ROLE_ADMIN')")
public ResponseEntity<ResponseWrapper> getError(...
INSERT INTO table USER_ROLE VALUES ('ADMIN','PASSWORD','ROLE_ADMIN');
How can the method "hasRole" query the table USER_ROLE? Is there any setting that I must give to Spring in order to communicate with that table?
The @PreAuthorize annotation checks the given expression before entering the method, whereas the @PostAuthorize annotation verifies it after the execution of the method and could alter the result.
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.
The real difference is that @PreAuthorize can work with Spring Expression Language (SpEL). You can: Access methods and properties of SecurityExpressionRoot . (Advanced feature) Add your own methods (override MethodSecurityExpressionHandler and set it as <global-method-security><expression-handler ... /></...> ).
The first way to check for user roles in Java is to use the @PreAuthorize annotation provided by Spring Security. This annotation can be applied to a class or method, and it accepts a single string value that represents a SpEL expression. Before we can use this annotation, we must first enable global method security.
Ensure you add the following to your configuration:
Annotation style:
@EnableGlobalMethodSecurity(prePostEnabled = true)
XML Style:
<global-method-security pre-post-annotations="enabled"/>
It's all in the spring docs.
Using @Pre
and @Post
annotations requires you to have first set up spring security in your project. User roles are loaded during authentication in the standard implementation.
It doesn't check your table when checking the annotation (by default), it just checks the Principal
(User) object in memory for the list of assigned GrantedAuthority
(Roles).
A closer look...
Take a look at the UserDetailsService interface, this returns an instance of UserDetails (the Principal
). This is where we fetch your "user" from the database.
The UserDetails
interface defines a method called getAuthorities()
that returns a Collection<? extends GrantedAuthority>
, essentially your Role
table. This is where the "Roles" make it into memory, and can be later checked by the @Pre
and @Post
annotations.
The implementation I've explained above can be found here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With