diff --git a/core/src/main/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandler.java b/core/src/main/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandler.java index 92d4252175..87245969c5 100644 --- a/core/src/main/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandler.java +++ b/core/src/main/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandler.java @@ -11,6 +11,7 @@ import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.access.hierarchicalroles.RoleHierarchy; import org.springframework.security.core.Authentication; +import org.springframework.util.Assert; /** * Base implementation of the facade which isolates Spring Security's requirements for evaluating security expressions @@ -20,7 +21,7 @@ import org.springframework.security.core.Authentication; * @since 3.1 */ public abstract class AbstractSecurityExpressionHandler implements SecurityExpressionHandler, ApplicationContextAware { - private final ExpressionParser expressionParser = new SpelExpressionParser(); + private ExpressionParser expressionParser = new SpelExpressionParser(); private BeanResolver br; private RoleHierarchy roleHierarchy; private PermissionEvaluator permissionEvaluator = new DenyAllPermissionEvaluator(); @@ -29,6 +30,11 @@ public abstract class AbstractSecurityExpressionHandler implements SecurityEx return expressionParser; } + public final void setExpressionParser(ExpressionParser expressionParser) { + Assert.notNull(expressionParser, "expressionParser cannot be null"); + this.expressionParser = expressionParser; + } + /** * Invokes the internal template methods to create {@code StandardEvaluationContext} and {@code SecurityExpressionRoot} * objects. diff --git a/core/src/test/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandlerTests.java b/core/src/test/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandlerTests.java index 741362c7d0..5e2dd70500 100644 --- a/core/src/test/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandlerTests.java +++ b/core/src/test/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandlerTests.java @@ -3,16 +3,15 @@ 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.junit.Before; +import org.junit.Test; 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.expression.spel.standard.SpelExpressionParser; import org.springframework.security.core.Authentication; -import java.util.*; - /** * @author Luke Taylor */ @@ -36,6 +35,18 @@ public class AbstractSecurityExpressionHandlerTests { Expression expression = handler.getExpressionParser().parseExpression("@number10.compareTo(@number20) < 0"); assertTrue((Boolean) expression.getValue(handler.createEvaluationContext(mock(Authentication.class), new Object()))); } + + @Test(expected=IllegalArgumentException.class) + public void setExpressionParserNull() { + handler.setExpressionParser(null); + } + + @Test + public void setExpressionParser() { + SpelExpressionParser parser = new SpelExpressionParser(); + handler.setExpressionParser(parser); + assertTrue(parser == handler.getExpressionParser()); + } } @Configuration