SEC-1491: Add support for an external priority SecurityMetadataSource to be referenced from global-method-security.
This commit is contained in:
parent
3084ad878f
commit
8d99918798
|
@ -79,6 +79,7 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
|
||||||
private static final String ATT_REF = "ref";
|
private static final String ATT_REF = "ref";
|
||||||
private static final String ATT_MODE = "mode";
|
private static final String ATT_MODE = "mode";
|
||||||
private static final String ATT_ADVICE_ORDER = "order";
|
private static final String ATT_ADVICE_ORDER = "order";
|
||||||
|
private static final String ATT_META_DATA_SOURCE_REF = "metadata-source-ref";
|
||||||
|
|
||||||
public BeanDefinition parse(Element element, ParserContext pc) {
|
public BeanDefinition parse(Element element, ParserContext pc) {
|
||||||
CompositeComponentDefinition compositeDef =
|
CompositeComponentDefinition compositeDef =
|
||||||
|
@ -97,6 +98,13 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
|
||||||
BeanDefinition preInvocationVoter = null;
|
BeanDefinition preInvocationVoter = null;
|
||||||
ManagedList<BeanMetadataElement> afterInvocationProviders = new ManagedList<BeanMetadataElement>();
|
ManagedList<BeanMetadataElement> afterInvocationProviders = new ManagedList<BeanMetadataElement>();
|
||||||
|
|
||||||
|
// Check for an external SecurityMetadataSource, which takes priority over other sources
|
||||||
|
String metaDataSourceId = element.getAttribute(ATT_META_DATA_SOURCE_REF);
|
||||||
|
|
||||||
|
if (StringUtils.hasText(metaDataSourceId)) {
|
||||||
|
delegates.add(new RuntimeBeanReference(metaDataSourceId));
|
||||||
|
}
|
||||||
|
|
||||||
if (prePostAnnotationsEnabled) {
|
if (prePostAnnotationsEnabled) {
|
||||||
Element prePostElt = DomUtils.getChildElementByTagName(element, INVOCATION_HANDLING);
|
Element prePostElt = DomUtils.getChildElementByTagName(element, INVOCATION_HANDLING);
|
||||||
Element expressionHandlerElt = DomUtils.getChildElementByTagName(element, EXPRESSION_HANDLER);
|
Element expressionHandlerElt = DomUtils.getChildElementByTagName(element, EXPRESSION_HANDLER);
|
||||||
|
|
|
@ -226,6 +226,8 @@ global-method-security.attlist &=
|
||||||
global-method-security.attlist &=
|
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.
|
## 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"}?
|
attribute mode {"aspectj"}?
|
||||||
|
global-method-security.attlist &=
|
||||||
|
attribute metadata-source-ref {xsd:token}?
|
||||||
|
|
||||||
after-invocation-provider =
|
after-invocation-provider =
|
||||||
## Allows addition of extra AfterInvocationProvider beans which should be called by the MethodSecurityInterceptor created by global-method-security.
|
## Allows addition of extra AfterInvocationProvider beans which should be called by the MethodSecurityInterceptor created by global-method-security.
|
||||||
|
|
|
@ -576,6 +576,7 @@
|
||||||
</xs:restriction>
|
</xs:restriction>
|
||||||
</xs:simpleType>
|
</xs:simpleType>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
|
<xs:attribute name="metadata-source-ref" type="xs:token"/>
|
||||||
</xs:attributeGroup>
|
</xs:attributeGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -346,6 +346,28 @@ public class GlobalMethodSecurityBeanDefinitionParserTests {
|
||||||
assertSame(ram, FieldUtils.getFieldValue(msi.getAdvice(), "runAsManager"));
|
assertSame(ram, FieldUtils.getFieldValue(msi.getAdvice(), "runAsManager"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void supportsExternalMetadataSource() throws Exception {
|
||||||
|
setContext(
|
||||||
|
"<b:bean id='target' class='" + ConcreteFoo.class.getName() + "'/>" +
|
||||||
|
"<method-security-metadata-source id='mds'>" +
|
||||||
|
" <protect method='"+ Foo.class.getName() + ".foo' access='ROLE_ADMIN'/>" +
|
||||||
|
"</method-security-metadata-source>" +
|
||||||
|
"<global-method-security pre-post-annotations='enabled' metadata-source-ref='mds'/>" + AUTH_PROVIDER_XML
|
||||||
|
);
|
||||||
|
// External MDS should take precedence over PreAuthorize
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(bob);
|
||||||
|
Foo foo = (Foo) appContext.getBean("target");
|
||||||
|
try {
|
||||||
|
foo.foo(new SecurityConfig("A"));
|
||||||
|
fail("Bob can't invoke admin methods");
|
||||||
|
} catch (AccessDeniedException expected) {
|
||||||
|
}
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken("admin", "password"));
|
||||||
|
foo.foo(new SecurityConfig("A"));
|
||||||
|
}
|
||||||
|
|
||||||
private void setContext(String context) {
|
private void setContext(String context) {
|
||||||
appContext = new InMemoryXmlApplicationContext(context);
|
appContext = new InMemoryXmlApplicationContext(context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,19 +16,18 @@ package org.springframework.security.access.annotation;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.*;
|
||||||
|
import org.springframework.security.access.ConfigAttribute;
|
||||||
|
import org.springframework.security.access.SecurityConfig;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Inherited;
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import org.junit.*;
|
|
||||||
import org.springframework.security.access.ConfigAttribute;
|
|
||||||
import org.springframework.security.access.SecurityConfig;
|
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link org.springframework.security.access.annotation.SecuredAnnotationSecurityMetadataSource}
|
* Tests for {@link org.springframework.security.access.annotation.SecuredAnnotationSecurityMetadataSource}
|
||||||
|
|
Loading…
Reference in New Issue