Spring Security方法安全和JSR250安全注解
最近,了解到Spring Security对方法安全的支持,在这里记录下Java中方法安全的注解规范,以及Spring Security方法安全对JSR250中安全注解的整合。
JSR250中的安全注解
RunAs
- 作用于类,方法执行时以特定角色运行。
java
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
- 作用于类或方法,限制特定角色访问方法。
java
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
- 作用于类或方法,允许所有用户访问方法。
java
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
- 作用于类或方法,拒绝所有用户访问方法。
java
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
- 作用于类,声明安全角色供其他注解使用。
java
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();
}
Spring Security方法安全
Spring Security
官方文档中写到除了在请求级别鉴权,同样也支持了对方法级别的鉴权。方法安全基于安全注解的方式对方法调用进行权限验证。Spring Security提供了 @PreAuthorize
, @PostAuthorize
, @PreFilter
,@PostFilter
等注解,同样支持JSR250中的安全注解@RolesAllowed
,@DenyAll
,@PermitAll
。
Spring Security
安全注解都是基于Spring AOP
实现,每种注解都有对应的MethodInterceptor做相关逻辑的判断。
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 |
无论@EnableMethodSecurity
还是@EnableReactiveMethodSecurity
会通过对应ImportSelector,像容器注入相关的配置类。