SEC-1723: Use standard SpEL syntax for accessing beans in the app context by name.
This commit is contained in:
parent
dd108041a0
commit
614d8c0321
|
@ -17,7 +17,8 @@ dependencies {
|
|||
"org.springframework:spring-test:$springVersion",
|
||||
"org.slf4j:jcl-over-slf4j:$slf4jVersion"
|
||||
|
||||
testRuntime "hsqldb:hsqldb:$hsqlVersion"
|
||||
testRuntime "hsqldb:hsqldb:$hsqlVersion",
|
||||
"cglib:cglib-nodep:$cglibVersion"
|
||||
}
|
||||
|
||||
// jdkVersion = System.properties['java.version']
|
||||
|
|
|
@ -2,6 +2,8 @@ package org.springframework.security.access.expression;
|
|||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.expression.BeanFactoryResolver;
|
||||
import org.springframework.expression.BeanResolver;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
|
@ -21,7 +23,7 @@ import org.springframework.security.core.Authentication;
|
|||
public abstract class AbstractSecurityExpressionHandler<T> implements SecurityExpressionHandler<T>, ApplicationContextAware {
|
||||
private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
|
||||
private final ExpressionParser expressionParser = new SpelExpressionParser();
|
||||
private ApplicationContextPropertyAccessor sxrpa = new ApplicationContextPropertyAccessor(null);
|
||||
private BeanResolver br;
|
||||
private RoleHierarchy roleHierarchy;
|
||||
|
||||
public final ExpressionParser getExpressionParser() {
|
||||
|
@ -42,7 +44,7 @@ public abstract class AbstractSecurityExpressionHandler<T> implements SecurityEx
|
|||
root.setTrustResolver(trustResolver);
|
||||
root.setRoleHierarchy(roleHierarchy);
|
||||
StandardEvaluationContext ctx = createEvaluationContextInternal(authentication, invocation);
|
||||
ctx.addPropertyAccessor(sxrpa);
|
||||
ctx.setBeanResolver(br);
|
||||
ctx.setRootObject(root);
|
||||
|
||||
return ctx;
|
||||
|
@ -76,6 +78,6 @@ public abstract class AbstractSecurityExpressionHandler<T> implements SecurityEx
|
|||
}
|
||||
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
sxrpa = new ApplicationContextPropertyAccessor(applicationContext);
|
||||
br = new BeanFactoryResolver(applicationContext);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
package org.springframework.security.access.expression;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
/**
|
||||
* General property accessor which resolves properties as bean names within an {@code ApplicationContext}.
|
||||
*/
|
||||
final class ApplicationContextPropertyAccessor implements PropertyAccessor {
|
||||
private final ApplicationContext ctx;
|
||||
|
||||
ApplicationContextPropertyAccessor(ApplicationContext ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
if (ctx == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ctx.containsBean(name);
|
||||
}
|
||||
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return new TypedValue(ctx.getBean(name));
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
||||
}
|
||||
|
||||
public Class[] getSpecificTargetClasses() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -45,7 +45,7 @@ public class ExpressionProtectedBusinessServiceImpl implements BusinessService {
|
|||
return someArray;
|
||||
}
|
||||
|
||||
@PreAuthorize("#x == 'x' and number.intValue() == 1294 ")
|
||||
@PreAuthorize("#x == 'x' and @number.intValue() == 1294 ")
|
||||
public void methodWithBeanNamePropertyAccessExpression(String x) {
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package org.springframework.security.access.expression;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import org.junit.*;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public class AbstractSecurityExpressionHandlerTests {
|
||||
private AbstractSecurityExpressionHandler<Object> handler;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
handler = new AbstractSecurityExpressionHandler<Object>() {
|
||||
@Override
|
||||
protected SecurityExpressionRoot createSecurityExpressionRoot(Authentication authentication, Object o) {
|
||||
return new SecurityExpressionRoot(authentication) {};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beanNamesAreCorrectlyResolved() throws Exception {
|
||||
handler.setApplicationContext(new AnnotationConfigApplicationContext(TestConfiguration.class));
|
||||
|
||||
Expression expression = handler.getExpressionParser().parseExpression("@number10.compareTo(@number20) < 0");
|
||||
assertTrue((Boolean) expression.getValue(handler.createEvaluationContext(mock(Authentication.class), new Object())));
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
Integer number10() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Bean
|
||||
Integer number20() {
|
||||
return 20;
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ import org.springframework.security.core.authority.AuthorityUtils;
|
|||
* @since 3.0
|
||||
*/
|
||||
public class SecurityExpressionRootTests {
|
||||
private final Authentication JOE = new TestingAuthenticationToken("joe", "pass", "A", "B");
|
||||
final static Authentication JOE = new TestingAuthenticationToken("joe", "pass", "A", "B");
|
||||
|
||||
@Test
|
||||
public void denyAllIsFalsePermitAllTrue() throws Exception {
|
||||
|
|
|
@ -11,6 +11,7 @@ jettyVersion = '6.1.22'
|
|||
hsqlVersion = '1.8.0.10'
|
||||
slf4jVersion = '1.6.1'
|
||||
logbackVersion = '0.9.24'
|
||||
cglibVersion = '2.2'
|
||||
|
||||
bundlorProperties = [
|
||||
version: version,
|
||||
|
|
|
@ -25,8 +25,8 @@ public class DefaultWebSecurityExpressionHandlerTests {
|
|||
|
||||
EvaluationContext ctx = handler.createEvaluationContext(mock(Authentication.class), mock(FilterInvocation.class));
|
||||
ExpressionParser parser = handler.getExpressionParser();
|
||||
assertTrue(parser.parseExpression("role.getAttribute() == 'ROLE_A'").getValue(ctx, Boolean.class));
|
||||
assertTrue(parser.parseExpression("role.attribute == 'ROLE_A'").getValue(ctx, Boolean.class));
|
||||
assertTrue(parser.parseExpression("@role.getAttribute() == 'ROLE_A'").getValue(ctx, Boolean.class));
|
||||
assertTrue(parser.parseExpression("@role.attribute == 'ROLE_A'").getValue(ctx, Boolean.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue