Skip to content

jsr250-spring-security

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) &#8212; 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做相关逻辑的判断。

AnnotationMethodInterceptorAuthorizationManager
@PreAuthorizeAuthorizationManagerBeforeMethodInterceptor#preAuthorizePreAuthorizeAuthorizationManager
@PostAuthorizeAuthorizationManagerAfterMethodInterceptor#postAuthorizePostAuthorizeAuthorizationManager
@PreFilterPreFilterAuthorizationMethodInterceptor
@PostFilterPostFilterAuthorizationMethodInterceptor
@SecuredAuthorizationManagerBeforeMethodInterceptor#securedSecuredAuthorizationManager
@RolesAllowed@DenyAll@PermitAllAuthorizationManagerBeforeMethodInterceptor#jsr250Jsr250AuthorizationManager

无论@EnableMethodSecurity还是@EnableReactiveMethodSecurity会通过对应ImportSelector,像容器注入相关的配置类。