SEC-1213: Added "order" atrribute to global-method-security

This commit is contained in:
Luke Taylor 2009-09-04 15:54:42 +00:00
parent ed0686cacf
commit 8632946f30
4 changed files with 36 additions and 9 deletions

View File

@ -75,8 +75,9 @@ 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_ADVICE_ORDER = "order";
@SuppressWarnings("unchecked")
// @SuppressWarnings("unchecked")
public BeanDefinition parse(Element element, ParserContext pc) {
CompositeComponentDefinition compositeDef =
new CompositeComponentDefinition(element.getTagName(), pc.extractSource(element));
@ -84,7 +85,7 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
Object source = pc.extractSource(element);
// The list of method metadata delegates
ManagedList delegates = new ManagedList();
ManagedList<BeanMetadataElement> delegates = new ManagedList<BeanMetadataElement>();
boolean jsr250Enabled = "enabled".equals(element.getAttribute(ATT_USE_JSR250));
boolean useSecured = "enabled".equals(element.getAttribute(ATT_USE_SECURED));
@ -165,9 +166,12 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
if (pointcutMap.size() > 0) {
// Only add it if there are actually any pointcuts defined.
MapBasedMethodSecurityMetadataSource mapBasedMethodSecurityMetadataSource = new MapBasedMethodSecurityMetadataSource();
delegates.add(mapBasedMethodSecurityMetadataSource);
registerProtectPointcutPostProcessor(pc, pointcutMap, mapBasedMethodSecurityMetadataSource, source);
BeanDefinition mapBasedMetadataSource = new RootBeanDefinition(MapBasedMethodSecurityMetadataSource.class);
BeanReference ref = new RuntimeBeanReference(pc.getReaderContext().registerWithGeneratedName(mapBasedMetadataSource));
delegates.add(ref);
pc.registerBeanComponent(new BeanComponentDefinition(mapBasedMetadataSource, ref.getBeanName()));
registerProtectPointcutPostProcessor(pc, pointcutMap, ref, source);
}
BeanReference metadataSource = registerDelegatingMethodSecurityMetadataSource(pc, delegates, source);
@ -190,10 +194,11 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
BeanReference interceptor = registerMethodSecurityInterceptor(pc, accessManagerId, runAsManagerId,
metadataSource, afterInvocationProviders, source);
registerAdvisor(pc, interceptor, metadataSource, source);
registerAdvisor(pc, interceptor, metadataSource, source, element.getAttribute(ATT_ADVICE_ORDER));
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(pc, element);
pc.popAndRegisterContainingComponent();
return null;
}
@ -241,7 +246,7 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
private void registerProtectPointcutPostProcessor(ParserContext parserContext,
Map<String, List<ConfigAttribute>> pointcutMap,
MapBasedMethodSecurityMetadataSource mapBasedMethodSecurityMetadataSource, Object source) {
BeanReference mapBasedMethodSecurityMetadataSource, Object source) {
RootBeanDefinition ppbp = new RootBeanDefinition(ProtectPointcutPostProcessor.class);
ppbp.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
ppbp.setSource(source);
@ -304,11 +309,16 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
return new RuntimeBeanReference(id);
}
private void registerAdvisor(ParserContext parserContext, BeanReference interceptor, BeanReference metadataSource, Object source) {
private void registerAdvisor(ParserContext parserContext, BeanReference interceptor, BeanReference metadataSource, Object source, String adviceOrder) {
if (parserContext.getRegistry().containsBeanDefinition(BeanIds.METHOD_SECURITY_METADATA_SOURCE_ADVISOR)) {
parserContext.getReaderContext().error("Duplicate <global-method-security> detected.", source);
}
RootBeanDefinition advisor = new RootBeanDefinition(MethodSecurityMetadataSourceAdvisor.class);
if (StringUtils.hasText(adviceOrder)) {
advisor.getPropertyValues().addPropertyValue("order", adviceOrder);
}
// advisor must be an infrastructure bean as Spring's InfrastructureAdvisorAutoProxyCreator will ignore it
// otherwise
advisor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

View File

@ -203,6 +203,9 @@ global-method-security.attlist &=
global-method-security.attlist &=
## Optional RunAsmanager implementation which will be used by the configured MethodSecurityInterceptor
attribute run-as-manager-ref {xsd:token}?
global-method-security.attlist &=
## Allows the advice "order" to be set for the method security interceptor.
attribute order {xsd:token}?
after-invocation-provider =
## Allows addition of extra AfterInvocationProvider beans which should be called by the MethodSecurityInterceptor created by global-method-security.

View File

@ -672,6 +672,12 @@
configured MethodSecurityInterceptor</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="order" type="xs:token">
<xs:annotation>
<xs:documentation>Allows the advice "order" to be set for the method security
interceptor.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:attributeGroup>
<xs:element name="custom-after-invocation-provider">
<xs:annotation>

View File

@ -8,6 +8,8 @@ import java.util.List;
import org.junit.After;
import org.junit.Test;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.Advised;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.ApplicationContext;
@ -46,7 +48,7 @@ public class GlobalMethodSecurityBeanDefinitionParserTests {
public void loadContext() {
setContext(
"<b:bean id='target' class='org.springframework.security.access.annotation.BusinessServiceImpl'/>" +
"<global-method-security>" +
"<global-method-security order='1001'>" +
" <protect-pointcut expression='execution(* *.someUser*(..))' access='ROLE_USER'/>" +
" <protect-pointcut expression='execution(* *.someAdmin*(..))' access='ROLE_ADMIN'/>" +
"</global-method-security>" + ConfigTestUtils.AUTH_PROVIDER_XML
@ -67,6 +69,7 @@ public class GlobalMethodSecurityBeanDefinitionParserTests {
@Test(expected=AuthenticationCredentialsNotFoundException.class)
public void targetShouldPreventProtectedMethodInvocationWithNoContext() {
loadContext();
target.someUserMethod1();
}
@ -77,6 +80,11 @@ public class GlobalMethodSecurityBeanDefinitionParserTests {
SecurityContextHolder.getContext().setAuthentication(token);
target.someUserMethod1();
// SEC-1213. Check the order
Advisor[] advisors = ((Advised)target).getAdvisors();
assertEquals(1, advisors.length);
assertEquals(1001, ((MethodSecurityMetadataSourceAdvisor)advisors[0]).getOrder());
}
@Test(expected=AccessDeniedException.class)