MethodSecurityInterceptor用于多个方法

Mic*_*che 6 java spring-security

我想使用Spring Security保护我的服务层.正如文档中所解释的,我需要使用一个MethodSecurityInterceptor来检查是否允许方法调用.

要确定是否允许给定用户进行服务方法调用,影响调用方法(使用MethodSecurityMetadataSource)所需的角色对我来说是不够的,因为它还取决于传递给方法的参数.正如文档中所建议的,我可以编写自定义AccessDecisionVoter并通过安全对象访问参数(MethodInvocation在本例中).

但是,我的授权逻辑在方法上是不同的.例如,多个方法之间的参数可能不同,授权逻辑也不同.

我看到两个选择:

  • 我可以使用条件逻辑AccessDecisionVoter来确定要使用的调用方法和授权逻辑,但它似乎是一个丑陋的解决方案.
  • 我可以为MethodSecurityInterceptor每个方法定义一个安全.根据Spring文档,a MethodSecurityInterceptor用于保护许多方法,因此它让我觉得还有另一种方法.

方法调用(使用AfterInvocationProvider)后的访问决策存在同样的问题.

有哪些替代方案?

Bor*_*hov 3

您可以基于Spring@PreAuthorize("")构建实现自己的方法安全注解。

要获取有关方法的额外信息(超出方法参数值)到 SpEL 评估上下文,您可以实现自己的 MethodSecurityExpressionHandler

@Service
public class MySecurityExpressionHandler extends
    DefaultMethodSecurityExpressionHandler {

    @Override
    public StandardEvaluationContext createEvaluationContextInternal(
        Authentication auth, MethodInvocation mi) {

    StandardEvaluationContext evaluationContext = super
            .createEvaluationContextInternal(auth, mi);

    SomeMethodInfoData methodInfoData = mi.getMethod(). ...;

    evaluationContext.setVariable("someData", <value computed based on method info data>);
    }

    return evaluationContext;
} 
Run Code Online (Sandbox Code Playgroud)

global-method-security并在您的声明中注册

<security:global-method-security
        pre-post-annotations="enabled">
        <security:expression-handler
            ref="mySecurityExpressionHandler" />
    </security:global-method-security>
Run Code Online (Sandbox Code Playgroud)

现在您可以创建自定义安全注释(如果需要,还可以在 MySecurityExpressionHandler 中创建额外的流程注释数据)

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("#<someData>")
public @interface CustomSecurityAnnotation { ... }
Run Code Online (Sandbox Code Playgroud)

例如,您可以创建自定义注释来检查用户角色,而不会弄乱字符串:

@MyUserRoleCheck(MyAppRole.Admin)
public void someMethod()
Run Code Online (Sandbox Code Playgroud)