1
0
mirror of synced 2026-05-22 21:33:16 +00:00

SEC-1294: Enable access to beans from ApplicationContext in EL expressions.

ExpressionHandlers are now ApplicationContextAware and set the app context on the SecurityExpressionRoot. A custom PropertyAccessor resolves the properties against the root by looking them up in the app context.
This commit is contained in:
Luke Taylor
2010-03-31 22:37:22 +01:00
parent 12a6ae2ffa
commit 0521d10069
12 changed files with 170 additions and 14 deletions
+3 -2
View File
@@ -6,6 +6,7 @@ dependencies {
compile project(':spring-security-core'),
project(':spring-security-web'),
"org.aspectj:aspectjweaver:$aspectjVersion",
'aopalliance:aopalliance:1.0',
"org.springframework:spring-aop:$springVersion",
"org.springframework:spring-context:$springVersion",
"org.springframework:spring-web:$springVersion",
@@ -17,10 +18,10 @@ dependencies {
project(':spring-security-openid'),
files(this.project(':spring-security-core').sourceSets.test.classesDir),
'javax.annotation:jsr250-api:1.0',
'aopalliance:aopalliance:1.0',
"org.springframework.ldap:spring-ldap-core:$springLdapVersion",
"org.springframework:spring-jdbc:$springVersion",
"org.springframework:spring-tx:$springVersion"
testRuntime "hsqldb:hsqldb:$hsqlVersion"
testRuntime "hsqldb:hsqldb:$hsqlVersion",
"cglib:cglib-nodep:2.2"
}
@@ -74,9 +74,7 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
if (StringUtils.hasText(expressionHandlerRef)) {
logger.info("Using bean '" + expressionHandlerRef + "' as web SecurityExpressionHandler implementation");
} else {
BeanDefinition expressionHandler = BeanDefinitionBuilder.rootBeanDefinition(DefaultWebSecurityExpressionHandler.class).getBeanDefinition();
expressionHandlerRef = pc.getReaderContext().generateBeanName(expressionHandler);
pc.registerBeanComponent(new BeanComponentDefinition(expressionHandler, expressionHandlerRef));
expressionHandlerRef = registerDefaultExpressionHandler(pc);
}
fidsBuilder = BeanDefinitionBuilder.rootBeanDefinition(ExpressionBasedFilterInvocationSecurityMetadataSource.class);
@@ -87,12 +85,19 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
fidsBuilder.addConstructorArgValue(requestToAttributesMap);
}
// fidsBuilder.addPropertyValue("stripQueryStringFromUrls", matcher instanceof AntUrlPathMatcher);
fidsBuilder.getRawBeanDefinition().setSource(pc.extractSource(elt));
return fidsBuilder.getBeanDefinition();
}
static String registerDefaultExpressionHandler(ParserContext pc) {
BeanDefinition expressionHandler = BeanDefinitionBuilder.rootBeanDefinition(DefaultWebSecurityExpressionHandler.class).getBeanDefinition();
String expressionHandlerRef = pc.getReaderContext().generateBeanName(expressionHandler);
pc.registerBeanComponent(new BeanComponentDefinition(expressionHandler, expressionHandlerRef));
return expressionHandlerRef;
}
static boolean isUseExpressions(Element elt) {
return "true".equals(elt.getAttribute(ATT_USE_EXPRESSIONS));
}
@@ -461,7 +461,12 @@ class HttpConfigurationBuilder {
ManagedList<BeanDefinition> voters = new ManagedList<BeanDefinition>(2);
if (useExpressions) {
voters.add(new RootBeanDefinition(WebExpressionVoter.class));
BeanDefinitionBuilder expressionVoter = BeanDefinitionBuilder.rootBeanDefinition(WebExpressionVoter.class);
RuntimeBeanReference expressionHandler = new RuntimeBeanReference(
FilterInvocationSecurityMetadataSourceParser.registerDefaultExpressionHandler(pc));
expressionVoter.addPropertyValue("expressionHandler", expressionHandler);
voters.add(expressionVoter.getBeanDefinition());
} else {
voters.add(new RootBeanDefinition(RoleVoter.class));
voters.add(new RootBeanDefinition(AuthenticatedVoter.class));
@@ -19,6 +19,7 @@ import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.access.annotation.BusinessService;
import org.springframework.security.access.annotation.ExpressionProtectedBusinessServiceImpl;
import org.springframework.security.access.intercept.AfterInvocationProviderManager;
import org.springframework.security.access.intercept.RunAsManagerImpl;
import org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor;
@@ -242,6 +243,20 @@ public class GlobalMethodSecurityBeanDefinitionParserTests {
target.someAdminMethod();
}
@Test
public void beanNameExpressionPropertyIsSupported() {
setContext(
"<global-method-security pre-post-annotations='enabled' proxy-target-class='true'/>" +
"<b:bean id='number' class='java.lang.Integer'>" +
" <b:constructor-arg value='1294'/>" +
"</b:bean>" +
"<b:bean id='target' class='org.springframework.security.access.annotation.ExpressionProtectedBusinessServiceImpl'/>" +
AUTH_PROVIDER_XML);
SecurityContextHolder.getContext().setAuthentication(bob);
ExpressionProtectedBusinessServiceImpl target = (ExpressionProtectedBusinessServiceImpl) appContext.getBean("target");
target.methodWithBeanNamePropertyAccessExpression("x");
}
@Test
public void preAndPostFilterAnnotationsWorkWithLists() {
setContext(