SEC-1232: GlobalMethodSecurityBeanDefinitionParser support for mode='aspectj'

Also added this syntax to the aspectj sample.
This commit is contained in:
Luke Taylor 2010-03-31 16:55:02 +01:00
parent 020e0aa49a
commit a3ef8255d8
6 changed files with 56 additions and 9 deletions

View File

@ -37,6 +37,7 @@ import org.springframework.security.access.expression.method.ExpressionBasedPreI
import org.springframework.security.access.intercept.AfterInvocationProviderManager;
import org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor;
import org.springframework.security.access.intercept.aopalliance.MethodSecurityMetadataSourceAdvisor;
import org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor;
import org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource;
import org.springframework.security.access.method.MapBasedMethodSecurityMetadataSource;
import org.springframework.security.access.prepost.PostInvocationAdviceProvider;
@ -76,6 +77,7 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
private static final String ATT_USE_SECURED = "secured-annotations";
private static final String ATT_USE_PREPOST = "pre-post-annotations";
private static final String ATT_REF = "ref";
private static final String ATT_MODE = "mode";
private static final String ATT_ADVICE_ORDER = "order";
public BeanDefinition parse(Element element, ParserContext pc) {
@ -90,6 +92,8 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
boolean jsr250Enabled = "enabled".equals(element.getAttribute(ATT_USE_JSR250));
boolean useSecured = "enabled".equals(element.getAttribute(ATT_USE_SECURED));
boolean prePostAnnotationsEnabled = "enabled".equals(element.getAttribute(ATT_USE_PREPOST));
boolean useAspectJ = "aspectj".equals(element.getAttribute(ATT_MODE));
BeanDefinition preInvocationVoter = null;
ManagedList<BeanMetadataElement> afterInvocationProviders = new ManagedList<BeanMetadataElement>();
@ -165,6 +169,9 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
DomUtils.getChildElementsByTagName(element, PROTECT_POINTCUT));
if (pointcutMap.size() > 0) {
if (useAspectJ) {
pc.getReaderContext().error("You can't use AspectJ mode with protect-pointcut definitions", source);
}
// Only add it if there are actually any pointcuts defined.
BeanDefinition mapBasedMetadataSource = new RootBeanDefinition(MapBasedMethodSecurityMetadataSource.class);
BeanReference ref = new RuntimeBeanReference(pc.getReaderContext().generateBeanName(mapBasedMetadataSource));
@ -190,13 +197,22 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
}
String runAsManagerId = element.getAttribute(ATT_RUN_AS_MGR);
BeanReference interceptor = registerMethodSecurityInterceptor(pc, accessManagerId, runAsManagerId,
metadataSource, afterInvocationProviders, source);
metadataSource, afterInvocationProviders, source, useAspectJ);
registerAdvisor(pc, interceptor, metadataSource, source, element.getAttribute(ATT_ADVICE_ORDER));
if (useAspectJ) {
BeanDefinitionBuilder aspect =
BeanDefinitionBuilder.rootBeanDefinition("org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect");
aspect.setFactoryMethod("aspectOf");
aspect.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
aspect.addPropertyValue("securityInterceptor", interceptor);
String id = pc.getReaderContext().registerWithGeneratedName(aspect.getBeanDefinition());
pc.registerBeanComponent(new BeanComponentDefinition(aspect.getBeanDefinition(), id));
} else {
registerAdvisor(pc, interceptor, metadataSource, source, element.getAttribute(ATT_ADVICE_ORDER));
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(pc, element);
}
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(pc, element);
pc.popAndRegisterContainingComponent();
return null;
@ -284,12 +300,16 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
}
private BeanReference registerMethodSecurityInterceptor(ParserContext pc, String accessManagerId,
String runAsManagerId, BeanReference metadataSource, List<BeanMetadataElement> afterInvocationProviders, Object source) {
BeanDefinitionBuilder bldr = BeanDefinitionBuilder.rootBeanDefinition(MethodSecurityInterceptor.class);
String runAsManagerId, BeanReference metadataSource,
List<BeanMetadataElement> afterInvocationProviders, Object source, boolean useAspectJ) {
BeanDefinitionBuilder bldr =
BeanDefinitionBuilder.rootBeanDefinition(useAspectJ ?
AspectJMethodSecurityInterceptor.class : MethodSecurityInterceptor.class);
bldr.getRawBeanDefinition().setSource(source);
bldr.addPropertyReference("accessDecisionManager", accessManagerId);
bldr.addPropertyValue("authenticationManager", new RootBeanDefinition(AuthenticationManagerDelegator.class));
bldr.addPropertyValue("securityMetadataSource", metadataSource);
if (StringUtils.hasText(runAsManagerId)) {
bldr.addPropertyReference("runAsManager", runAsManagerId);
}

View File

@ -216,6 +216,9 @@ global-method-security.attlist &=
attribute order {xsd:token}?
global-method-security.attlist &=
attribute proxy-target-class {boolean}?
global-method-security.attlist &=
## Can be used to specify that AspectJ should be used instead of the default Spring AOP. If set, secured classes must be woven with the AnnotationSecurityAspect from the spring-security-aspects module.
attribute mode {"aspectj"}?
after-invocation-provider =
## Allows addition of extra AfterInvocationProvider beans which should be called by the MethodSecurityInterceptor created by global-method-security.

View File

@ -574,6 +574,16 @@
</xs:annotation>
</xs:attribute>
<xs:attribute name="proxy-target-class" type="security:boolean"/>
<xs:attribute name="mode">
<xs:annotation>
<xs:documentation>Can be used to specify that AspectJ should be used instead of the default Spring AOP. If set, secured classes must be woven with the AnnotationSecurityAspect from the spring-security-aspects module.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="aspectj"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:attributeGroup>

View File

@ -0,0 +1,9 @@
dependencies {
compile project(':spring-security-core')
aspectpath project(':spring-security-aspects')
runtime project(':spring-security-config'),
project(':spring-security-aspects')
}

View File

@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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-3.0.xsd">
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<sec:global-method-security secured-annotations="enabled" mode="aspectj" />
<!--
<bean id="aspectJSecurityInterceptor"
class="org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager" />
@ -36,7 +40,7 @@
factory-method="aspectOf">
<property name="securityInterceptor" ref="aspectJSecurityInterceptor" />
</bean>
-->
<bean class="sample.aspectj.Service" />
<bean class="sample.aspectj.SecuredService" />

View File

@ -13,7 +13,8 @@ def String[] modules = [
def String[] samples = [
'tutorial',
'contacts',
'openid'
'openid',
'aspectj'
]
def String[] docs = [