Method Security in Spring Security And JSR250 Security Annotations
Recently, I learned about Spring Security's support for method security. Here, I will document the annotation specifications for method security in Java, as well as the integration of Spring Security method security with the security annotations in JSR250.
Secured Annotations in JSR250
RunAs
- Applied to the class, the method executes with a specific role.
package jakarta.annotation.security;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
/**
* Defines the identity of the application during execution.
* This allows developers to execute an application under a particular role.
* The role must map to the user / group information in the container's
* security realm. Its value is the name of a security role.
*
* @since Common Annotations 1.0
*/
@Documented
@Retention (RUNTIME)
@Target(TYPE)
public @interface RunAs {
/**
* Name of a security role.
*/
String value();
}
RolesAllowed
- Applied to the class or method, it restricts specific roles from accessing the method.
package jakarta.annotation.security;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
/**
* Specifies the list of security roles permitted to access method(s) in an
* application. The value of the <code>RolesAllowed</code> annotation
* is a list of security role names.
* This annotation can be specified on a class or on method(s). Specifying it
* at a class level means that it applies to all the methods in the class.
* Specifying it on a method means that it is applicable to that method only.
* If applied at both the class and methods level, the method value overrides
* the class value if the two conflict.
*
* @since Common Annotations 1.0
*/
@Documented
@Retention (RUNTIME)
@Target({TYPE, METHOD})
public @interface RolesAllowed {
/**
* List of roles that are permitted access.
*/
String[] value();
}
PermitAll
- Applied to the class or method, it allows all users to access the method.
package jakarta.annotation.security;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
/**
* Specifies that all security roles are allowed to invoke the specified
* method(s) — i.e., that the specified method(s) are "unchecked".
* It can be specified on a class or on methods. Specifying it on the class
* means that it applies to all methods of the class. If specified at the
* method level, it only affects that method. If the <code>RolesAllowed</code>
* annotation is specified at the class level and this annotation is
* applied at the method level, the <code>PermitAll</code>
* annotation overrides the <code>RolesAllowed</code> annotation for
* the specified method.
*
* @see jakarta.annotation.security.RolesAllowed
* @see jakarta.annotation.security.DenyAll
*
* @since Common Annotations 1.0
*/
@Documented
@Retention (RUNTIME)
@Target({TYPE, METHOD})
public @interface PermitAll {
}
DenyAll
- Applied to the class or method, it denies all users access to the method.
package jakarta.annotation.security;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
/**
* Specifies that no security roles are allowed to invoke the specified
* method(s).
*
* @see jakarta.annotation.security.RolesAllowed
* @see jakarta.annotation.security.PermitAll
* @since Common Annotations 1.0
*/
@Documented
@Retention (RUNTIME)
@Target({TYPE, METHOD})
public @interface DenyAll {
}
DeclareRoles
- Applied to the class, it declares security roles for use by other annotations.
package jakarta.annotation.security;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
/**
* Used by application to declare security roles. It can be
* specified on a class. The value of the <code>DeclareRoles</code>
* annotation is a list of security role names.
*
* @since Common Annotations 1.0
*/
@Documented
@Retention (RUNTIME)
@Target(TYPE)
public @interface DeclareRoles {
/**
* List of security role names.
*/
String[] value();
}
Method security in Spring Security
Spring Security
official documentation states that in addition to request-level authorization, method-level authorization is also supported. Method security performs permission verification on method calls based on security annotations. Spring Security provides annotations such as @PreAuthorize
, @PostAuthorize
, @PreFilter
, and @PostFilter
, and also supports the security annotations from JSR250, including @RolesAllowed
, @DenyAll
, and @PermitAll
.
Spring Security
's security annotations are implemented based on Spring AOP
, with each annotation having a corresponding MethodInterceptor that handles the relevant logic checks.
Annotation | MethodInterceptor | AuthorizationManager |
---|---|---|
@PreAuthorize | AuthorizationManagerBeforeMethodInterceptor#preAuthorize | PreAuthorizeAuthorizationManager |
@PostAuthorize | AuthorizationManagerAfterMethodInterceptor#postAuthorize | PostAuthorizeAuthorizationManager |
@PreFilter | PreFilterAuthorizationMethodInterceptor | |
@PostFilter | PostFilterAuthorizationMethodInterceptor | |
@Secured | AuthorizationManagerBeforeMethodInterceptor#secured | SecuredAuthorizationManager |
@RolesAllowed ,@DenyAll ,@PermitAll | AuthorizationManagerBeforeMethodInterceptor#jsr250 | Jsr250AuthorizationManager |
Whether @EnableMethodSecurity
or @EnableReactiveMethodSecurity
, they will inject the relevant configuration classes into the container through the corresponding ImportSelector.