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:
+9
-4
@@ -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));
|
||||
}
|
||||
|
||||
+6
-1
@@ -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));
|
||||
|
||||
+15
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user