Spring安全性 - 为什么RoleVoter支持所有类,而WebExpressionVoter只支持FilterInvocation的子类?

Dau*_*aud 5 spring spring-security spring-3

supports(Class clazz)方法中RoleVoter,它总是返回true表示

此实现支持任何类型的类,因为它不查询呈现的安全对象.

什么是" 呈现的安全对象 ".另一方面,只有在子类型为的情况下才返回true 的supports(Class clazz)方法.这里是"呈现的安全对象",为什么选民必须支持它?WebExpressionVoterclazzFilterInvocationFilterInvocation

如果我@Secured对我的方法使用注释并为具有WebExpressionVoter选民之一的全局方法安全性配置访问决策管理器,则会出现错误

AccessDecisionManager不支持安全对象类:interface org.aopalliance.intercept.MethodInvocation

这是因为访问决策管理器的所有选民(当配置为方法安全性时)必须支持上述类,而RoleVoter其他人则WebExpressionVoter需要支持子类型FilterInvocation.

SPEL@PreAuthorize标签中的表达式也需要WebExpressionVoter,并且还需要支持MethodInvocation类,而不是.但它确实有效.那我在这里错了什么?

Roa*_*ner 14

secured object是一个代表任何安全的摘要.它可能是一个MethodInvocation的情况下@Secured,@RolesAllowed,@PreFilter@PreAuthorize,或一FilterInvocation在箱子<intercept-url />如果需要或任何其他对象.

@PreFilter@PreAuthorize注释被处理PreInvocationAuthorizationAdviceVoter.它使用the MethodInvocation来获取注释及其属性值,因此它具有:

public boolean supports(Class<?> clazz) {
    return clazz.isAssignableFrom(MethodInvocation.class);
}
Run Code Online (Sandbox Code Playgroud)

WebExpressionVoter是网络调用特定的,因为它的URL自该模式相匹配<intercept-url />,这就是为什么它具有:

public boolean supports(Class<?> clazz) {
    return clazz.isAssignableFrom(FilterInvocation.class);
}
Run Code Online (Sandbox Code Playgroud)

RoleVoter仅使用Authentication对象的内容,所以它不依赖于secured object,这就是为什么它具有:

public boolean supports(Class<?> clazz) {
    return true;
}
Run Code Online (Sandbox Code Playgroud)

请注意,您可以单独AccessDecisionManager使用URL级别安全性和方法级别安全性.第一个将使用支持的选民FilterInvocation,而另一个支持的选民MethodInvocation.另请注意,它RoleVoter支持两者,因此可以在两种上下文中使用.