I am trying to move from XML Config to JavaConfig with spring-security 4.0.0.M1
This is my Configuration which works:
@Configuration
@ImportResource("classpath:applicationContext-security.xml")
public class MethodSecurityXmlConfig
{}
and 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>
I have service methods like this:
@Transactional(readOnly = false)
@PreAuthorize("hasPermission(#form, 'idForm')")
public boolean runAction ( IdForm form, Errors errors ) throws Exception {...}
Additionally I have an Aspect Ordering Advice like this as my PermissionEvaluator needs a Transaction too. So Transactional
should run before Security.
public aspect AspectOrdering
{
declare precedence : AnnotationTransactionAspect, *SecurityAspect;
}
I do compile time weaving with maven with spring-security-aspects. If I debug it I can see AspectJMethodSecurityInterceptor
is being invoked on this method (after Transactional..).
So, this just works fine.
Now I only switch from my MethodSecurityXmlConfig to this configuration class:
@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;
}
}
The method call is still intercepted by Spring Security but it does not do it with AspectJ Mode, it uses AopProxy!
And because of not using AspectJ my ordering isn't working, so Spring Security runs before @Transactional.
When I debug this, I can see MethodSecurityInterceptor
being invoked, but not AspectJMethodSecurityInterceptor
. The method is still advised but AspectJMethodSecurityInterceptor might never get called because the AnnotationSecurityAspect is not configured and calls return proceed() as it does not have access to an AspectJMethodSecurityInterceptor.
For me it seems to be a bug. Before raising an issue I would like to ask:
Did I miss some configuration to get Method Security with AspectJ working?