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 @EnableGlobalMethodSecurity
annotation.
@EnableGlobalMethodSecurity
provides prePostEnabled
, securedEnabled
and jsr250Enabled
. You can choose to use one or more of these three methods as needed.
@EnableGlobalMethodSecurity
The @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
Enabled when prePostEnabled
is equal to true
.
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.
SpEL expressions | Descriptions |
---|---|
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 true
.
These two annotations can be seen as enhancements to @PreAuthorize
and @PostAuthorize
. They implement @PreAuthorize
and @PostAuthorize
in addition to the ability to filter request response data. The data types restricted to processing are Collection
, Array
, Map
, 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
ids
that does not start withf
is removed and the return value isfelord
.
The underlying filter element is
java.util.Collection#remove(Object)
; in addition multiple input parameters need to usefilterTarget
to 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.
@Secured
Enabled when securedEnabled
is equal to true
.
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.
@Secured
is equivalent tohasAnyAuthority
.
JSR-250
Enabled when jsr250Enabled
is equal to true
.
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
@Secured
above.
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.