SEC-1213: Added "order" atrribute to global-method-security
This commit is contained in:
parent
ed0686cacf
commit
8632946f30
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue