Spring Security provides annotation-based access control.
turns on method annotation access control
Spring Security turns off method annotations by default, to turn it on just add the
jsr250Enabled. You can choose to use one or more of these three methods as needed.
@EnableGlobalMethodSecurity mind map can help you sort out the logic.
The yellow area is the basic knowledge of annotated access control and needs to be focused on, so let’s take a look at the basic usage.
@PreAuthorize and @PostAuthorize
prePostEnabled is equal to
The SpEL expression is used to calculate whether the method can be invoked or whether the result can be returned after the invocation, either before or after the marked method is invoked. Some examples of common expressions are summarized.
|principal.username ne ‘felord’||The current principal’s username cannot be felord|
|authentication.authorities.contains(‘ROLE_ADMIN’)||The authorities of the current Authentication contain ROLE_ADMIN|
|hasRole(‘ADMIN’)||The current user must have the role ROLE_ADMIN, equivalent to the above|
|hasAnyRole(‘ADMIN’,‘USER’)||Current user role must have ROLE_ADMIN or ROLE_USER|
|hasAuthority(‘ROLE_ADMIN’)||Same as hasRole|
|hasAnyAuthority(‘ROLE_ADMIN’,‘ROLE_USER’)||Same as hasAnyRole|
|#requestParam eq ‘felord’||The current request parameter requestParam (which can be an object, here is a string example) has a value equal to felord.|
Other expressions can be found in the official SpEL documentation.
If the user
felord accesses the following interface, the method will not only not execute but will also respond with a 403 exception status code.
If the annotation on the method is changed to
@PostAuthorize("authentication.principal.username ne 'felord'") , the console will print the following.
It is clear from the logs that the method did execute, but it still responded with a 403 status code.
@PreFilter and @PostFilter
are enabled when
prePostEnabled is equal to
These two annotations can be seen as enhancements to
@PostAuthorize. They implement
@PostAuthorize in addition to the ability to filter request response data. The data types restricted to processing are
Stream. As an example.
The above interface method has two levels of meaning.
The current user must hold the role
ROLE_ADMIN, otherwise the method is not executed. The method must be executed if this condition does not exist.
If the method executes, any element in the set of input
idsthat does not start with
fis removed and the return value is
The underlying filter element is
java.util.Collection#remove(Object); in addition multiple input parameters need to use
filterTargetto specify the parameter name.
@PostFilter is also well understood, take the following method as an example.
The method is executed regardless of whether the expression in the
@PostFilter holds or not. If the condition holds, the list data is responded to. If the condition is not valid, the response is a 403 status code.
These two annotations are used to control the request, the collection in the response, and the data in the stream.
securedEnabled is equal to
This annotation is much simpler and by default can only make access control decisions based on a collection of roles (which by default requires the prefix
ROLE_). The mechanism of this annotation is that it can be accessed as long as the set of roles it declares (
value) contains any role held by the current user. That is, there must be a non-empty intersection of the user’s role set and the role set of the
@Secured annotation. Decision making using SpEL expressions is not supported.
This is not demonstrated because it is too simple.
@Securedis equivalent to
jsr250Enabled is equal to
Enables the JSR-250 security control annotation, which is part of the JavaEE security specification (now a jakarta project). The following three of the JavaEE security annotations are used in Spring Security.
@DenyAll deny all access.
@PermitAll agrees to all accesses.
@RolesAllowed is used in the same way as
Advantages and disadvantages of annotation control
The advantage of using annotations is that the interface methods are bound and the control granularity is very fine, and you can even do some data level access control. The disadvantage is that it is statically woven into the Java code and flexibility is difficult to grasp.