带有@EnableGlobalMethodSecurity的Spring Security AspectJMode无法正常工作

时间:2014-08-08 16:23:44

标签: spring-security aspectj

我正在尝试使用spring-security 4.0.0.M1从XML Config迁移到JavaConfig

这是我的配置有效:

@Configuration
@ImportResource("classpath:applicationContext-security.xml")
public class MethodSecurityXmlConfig
{}

和applicationContext-security.xml

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:security="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security.xsd
     ">
    <security:global-method-security mode="aspectj" proxy-target-class="false" pre-post-annotations="enabled">
        <security:expression-handler ref="expressionHandler" />
    </security:global-method-security>

    <bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
        <property name="permissionEvaluator" ref="delegatingPermissionEvaluator" />
    </bean>
</beans>

我有这样的服务方法:

@Transactional(readOnly = false)
@PreAuthorize("hasPermission(#form, 'idForm')")
public boolean runAction ( IdForm form, Errors errors ) throws Exception {...}

另外,我有一个像这样的Aspect Ordering Advice,因为我的PermissionEvaluator也需要一个Transaction。所以Transactional应该在安全之前运行。

public aspect AspectOrdering
{
    declare precedence : AnnotationTransactionAspect, *SecurityAspect;
}

我编译时使用带有spring-security-aspects的maven进行编织。如果我调试它,我可以看到在此方法上调用AspectJMethodSecurityInterceptor(在Transactional ...之后) 所以,这只是工作正常。

现在我只从我的MethodSecurityXmlConfig切换到此配置类:

@Configuration
@EnableGlobalMethodSecurity(mode = AdviceMode.ASPECTJ, prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration
{
    @Resource
    private DelegatingPermissionEvaluator   delegatingPermissionEvaluator;

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler ( )
    {
        DefaultMethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler = new DefaultMethodSecurityExpressionHandler();
        defaultMethodSecurityExpressionHandler.setPermissionEvaluator(delegatingPermissionEvaluator);
        return defaultMethodSecurityExpressionHandler;
    }
}

方法调用仍然被Spring Security拦截,但它没有使用AspectJ模式,它使用AopProxy!

由于没有使用AspectJ,我的订单无效,所以Spring Security在@Transactional之前运行。

当我调试这个时,我可以看到MethodSecurityInterceptor被调用,但不是AspectJMethodSecurityInterceptor。仍然建议使用该方法,但可能永远不会调用AspectJMethodSecurityInterceptor,因为未配置AnnotationSecurityAspect并且调用返回proceed(),因为它无权访问AspectJMethodSecurityInterceptor。

对我来说,它似乎是一个错误。在提出问题之前,我想问一下:

我是否错过了使用AspectJ工作的方法安全性的一些配置?

2 个答案:

答案 0 :(得分:0)

这个元素不连贯:

<security:global-method-security mode="aspectj" proxy-target-class="false" pre-post-annotations="enabled">

根据Spring Security参考手册/附录/安全命名空间/方法安全性/&lt; global-method-security&gt; :

  • mode =“aspectj”:此属性可以设置为“aspectj”以指定应该使用AspectJ而不是默认的Spring AOP
  • proxy-target-class =“false”: proxy-target-class如果为true,将使用基于类的代理而不是基于接口的代理

您要求JDK代理和AspectJ模式。首先删除proxy-target-class="false",然后安装AspectJ编织机制(如果尚未安装)。

答案 1 :(得分:0)

这是Spring Security 4.0.0.M1中的错误,请参阅https://jira.spring.io/browse/SEC-2698