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_MODE = "mode";
|
||||
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) {
|
||||
CompositeComponentDefinition compositeDef =
|
||||
|
@ -97,6 +98,13 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
|
|||
BeanDefinition preInvocationVoter = null;
|
||||
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) {
|
||||
Element prePostElt = DomUtils.getChildElementByTagName(element, INVOCATION_HANDLING);
|
||||
Element expressionHandlerElt = DomUtils.getChildElementByTagName(element, EXPRESSION_HANDLER);
|
||||
|
|
|
@ -226,6 +226,8 @@ 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.
|
||||
attribute mode {"aspectj"}?
|
||||
global-method-security.attlist &=
|
||||
attribute metadata-source-ref {xsd:token}?
|
||||
|
||||
after-invocation-provider =
|
||||
## 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:simpleType>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="metadata-source-ref" type="xs:token"/>
|
||||
</xs:attributeGroup>
|
||||
|
||||
|
||||
|
|
|
@ -346,6 +346,28 @@ public class GlobalMethodSecurityBeanDefinitionParserTests {
|
|||
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) {
|
||||
appContext = new InMemoryXmlApplicationContext(context);
|
||||
}
|
||||
|
|
|
@ -16,19 +16,18 @@ package org.springframework.security.access.annotation;
|
|||
|
||||
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.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Method;
|
||||
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}
|
||||
|
|
Loading…
Reference in New Issue