我正在尝试使用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工作的方法安全性的一些配置?
答案 0 :(得分:0)
这个元素不连贯:
<security:global-method-security mode="aspectj" proxy-target-class="false" pre-post-annotations="enabled">
根据Spring Security参考手册/附录/安全命名空间/方法安全性/&lt; global-method-security&gt; :
您要求JDK代理和AspectJ模式。首先删除proxy-target-class="false"
,然后安装AspectJ编织机制(如果尚未安装)。
答案 1 :(得分:0)
这是Spring Security 4.0.0.M1中的错误,请参阅https://jira.spring.io/browse/SEC-2698