diff --git a/core/src/main/java/org/springframework/security/config/ConfigUtils.java b/core/src/main/java/org/springframework/security/config/ConfigUtils.java index bfb75a8d89..eebfa2311e 100644 --- a/core/src/main/java/org/springframework/security/config/ConfigUtils.java +++ b/core/src/main/java/org/springframework/security/config/ConfigUtils.java @@ -13,7 +13,7 @@ import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.security.afterinvocation.AfterInvocationProviderManager; -import org.springframework.security.expression.support.MethodExpressionVoter; +import org.springframework.security.expression.method.MethodExpressionVoter; import org.springframework.security.util.UrlUtils; import org.springframework.security.vote.AffirmativeBased; import org.springframework.security.vote.AuthenticatedVoter; diff --git a/core/src/main/java/org/springframework/security/config/GlobalMethodSecurityBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/GlobalMethodSecurityBeanDefinitionParser.java index 41c18c857c..a656c12d34 100644 --- a/core/src/main/java/org/springframework/security/config/GlobalMethodSecurityBeanDefinitionParser.java +++ b/core/src/main/java/org/springframework/security/config/GlobalMethodSecurityBeanDefinitionParser.java @@ -19,9 +19,9 @@ import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.security.ConfigAttribute; import org.springframework.security.SecurityConfig; -import org.springframework.security.expression.DefaultSecurityExpressionHandler; -import org.springframework.security.expression.support.MethodExpressionAfterInvocationProvider; -import org.springframework.security.expression.support.MethodExpressionVoter; +import org.springframework.security.expression.method.MethodExpressionAfterInvocationProvider; +import org.springframework.security.expression.method.MethodExpressionVoter; +import org.springframework.security.expression.support.DefaultSecurityExpressionHandler; import org.springframework.security.intercept.method.DelegatingMethodDefinitionSource; import org.springframework.security.intercept.method.MapBasedMethodDefinitionSource; import org.springframework.security.intercept.method.ProtectPointcutPostProcessor; @@ -46,7 +46,7 @@ class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionParser { static final String SECURED_DEPENDENCY_CLASS = "org.springframework.security.annotation.Secured"; static final String SECURED_METHOD_DEFINITION_SOURCE_CLASS = "org.springframework.security.annotation.SecuredMethodDefinitionSource"; - static final String EXPRESSION_METHOD_DEFINITION_SOURCE_CLASS = "org.springframework.security.expression.support.ExpressionAnnotationMethodDefinitionSource"; + static final String EXPRESSION_METHOD_DEFINITION_SOURCE_CLASS = "org.springframework.security.expression.method.ExpressionAnnotationMethodDefinitionSource"; static final String JSR_250_SECURITY_METHOD_DEFINITION_SOURCE_CLASS = "org.springframework.security.annotation.Jsr250MethodDefinitionSource"; static final String JSR_250_VOTER_CLASS = "org.springframework.security.annotation.Jsr250Voter"; diff --git a/core/src/main/java/org/springframework/security/expression/ExpressionUtils.java b/core/src/main/java/org/springframework/security/expression/ExpressionUtils.java index 48a9777b72..5455771490 100644 --- a/core/src/main/java/org/springframework/security/expression/ExpressionUtils.java +++ b/core/src/main/java/org/springframework/security/expression/ExpressionUtils.java @@ -1,10 +1,5 @@ package org.springframework.security.expression; -import java.lang.reflect.Array; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - import org.springframework.expression.EvaluationContext; import org.springframework.expression.EvaluationException; import org.springframework.expression.Expression; @@ -18,6 +13,4 @@ public class ExpressionUtils { throw new IllegalArgumentException("Failed to evaluate expression", e); } } - - } diff --git a/core/src/main/java/org/springframework/security/expression/MethodInvocationSecurityExpressionRoot.java b/core/src/main/java/org/springframework/security/expression/MethodInvocationSecurityExpressionRoot.java deleted file mode 100644 index 47dc93392e..0000000000 --- a/core/src/main/java/org/springframework/security/expression/MethodInvocationSecurityExpressionRoot.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.springframework.security.expression; - -import org.springframework.security.Authentication; - -public class MethodInvocationSecurityExpressionRoot extends SecurityExpressionRoot { - - MethodInvocationSecurityExpressionRoot(Authentication a) { - super(a); - } - -} diff --git a/core/src/main/java/org/springframework/security/expression/SecurityExpressionHandler.java b/core/src/main/java/org/springframework/security/expression/SecurityExpressionHandler.java index 2b795dd279..43c9816e4e 100644 --- a/core/src/main/java/org/springframework/security/expression/SecurityExpressionHandler.java +++ b/core/src/main/java/org/springframework/security/expression/SecurityExpressionHandler.java @@ -4,6 +4,7 @@ import org.aopalliance.intercept.MethodInvocation; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.security.Authentication; +import org.springframework.security.intercept.web.FilterInvocation; /** * Facade which isolates Spring Security's requirements from the implementation of the underlying @@ -18,15 +19,21 @@ public interface SecurityExpressionHandler { /** * Provides a evaluation context in which to evaluate security expressions for a method invocation. */ - EvaluationContext createEvaluationContext(Authentication auth, MethodInvocation mi); + EvaluationContext createEvaluationContext(Authentication authentication, MethodInvocation mi); + + /** + * Provides a evaluation context in which to evaluate security expressions for a web invocation. + */ + EvaluationContext createEvaluationContext(Authentication authentication, FilterInvocation fi); /** * Filters a target collection or array. + * Only applies to method invocations. * * @param filterTarget the array or collection to be filtered. * @param filterExpression the expression which should be used as the filter condition. If it returns false on * evaluation, the object will be removed from the returned collection - * @param ctx the current evaluation context (usualy as created through a call to + * @param ctx the current evaluation context (as created through a call to * {@link #createEvaluationContext(Authentication, MethodInvocation)} * @return the filtered collection or array */ @@ -34,9 +41,11 @@ public interface SecurityExpressionHandler { /** * Used to inform the expression system of the return object for the given evaluation context. + * Only applies to method invocations. * * @param returnObject the return object value - * @param ctx the context within which the object should be set + * @param ctx the context within which the object should be set (as created through a call to + * {@link #createEvaluationContext(Authentication, MethodInvocation)} */ void setReturnObject(Object returnObject, EvaluationContext ctx); diff --git a/core/src/main/java/org/springframework/security/expression/support/AbstractExpressionBasedMethodConfigAttribute.java b/core/src/main/java/org/springframework/security/expression/method/AbstractExpressionBasedMethodConfigAttribute.java similarity index 94% rename from core/src/main/java/org/springframework/security/expression/support/AbstractExpressionBasedMethodConfigAttribute.java rename to core/src/main/java/org/springframework/security/expression/method/AbstractExpressionBasedMethodConfigAttribute.java index d1f2d071c1..e960fc2755 100644 --- a/core/src/main/java/org/springframework/security/expression/support/AbstractExpressionBasedMethodConfigAttribute.java +++ b/core/src/main/java/org/springframework/security/expression/method/AbstractExpressionBasedMethodConfigAttribute.java @@ -1,4 +1,4 @@ -package org.springframework.security.expression.support; +package org.springframework.security.expression.method; import org.springframework.expression.Expression; import org.springframework.expression.ParseException; @@ -33,7 +33,6 @@ abstract class AbstractExpressionBasedMethodConfigAttribute implements ConfigAtt AbstractExpressionBasedMethodConfigAttribute(Expression filterExpression, Expression authorizeExpression) throws ParseException { Assert.isTrue(filterExpression != null || authorizeExpression != null, "Filter and authorization Expressions cannot both be null"); - SpelExpressionParser parser = new SpelExpressionParser(); this.filterExpression = filterExpression == null ? null : filterExpression; this.authorizeExpression = authorizeExpression == null ? null : authorizeExpression; } diff --git a/core/src/main/java/org/springframework/security/expression/support/ExpressionAnnotationMethodDefinitionSource.java b/core/src/main/java/org/springframework/security/expression/method/ExpressionAnnotationMethodDefinitionSource.java similarity index 99% rename from core/src/main/java/org/springframework/security/expression/support/ExpressionAnnotationMethodDefinitionSource.java rename to core/src/main/java/org/springframework/security/expression/method/ExpressionAnnotationMethodDefinitionSource.java index 198b0e2fe2..3c7fe59bc1 100644 --- a/core/src/main/java/org/springframework/security/expression/support/ExpressionAnnotationMethodDefinitionSource.java +++ b/core/src/main/java/org/springframework/security/expression/method/ExpressionAnnotationMethodDefinitionSource.java @@ -1,4 +1,4 @@ -package org.springframework.security.expression.support; +package org.springframework.security.expression.method; import java.lang.annotation.Annotation; import java.lang.reflect.Method; diff --git a/core/src/main/java/org/springframework/security/expression/support/MethodExpressionAfterInvocationProvider.java b/core/src/main/java/org/springframework/security/expression/method/MethodExpressionAfterInvocationProvider.java similarity index 96% rename from core/src/main/java/org/springframework/security/expression/support/MethodExpressionAfterInvocationProvider.java rename to core/src/main/java/org/springframework/security/expression/method/MethodExpressionAfterInvocationProvider.java index bf1d829495..69ade8c5dd 100644 --- a/core/src/main/java/org/springframework/security/expression/support/MethodExpressionAfterInvocationProvider.java +++ b/core/src/main/java/org/springframework/security/expression/method/MethodExpressionAfterInvocationProvider.java @@ -1,4 +1,4 @@ -package org.springframework.security.expression.support; +package org.springframework.security.expression.method; import java.util.List; @@ -11,9 +11,9 @@ import org.springframework.security.AccessDeniedException; import org.springframework.security.Authentication; import org.springframework.security.ConfigAttribute; import org.springframework.security.afterinvocation.AfterInvocationProvider; -import org.springframework.security.expression.DefaultSecurityExpressionHandler; import org.springframework.security.expression.ExpressionUtils; import org.springframework.security.expression.SecurityExpressionHandler; +import org.springframework.security.expression.support.DefaultSecurityExpressionHandler; /** * AfterInvocationProvider which handles the @PostAuthorize and @PostFilter annotation expressions. diff --git a/core/src/main/java/org/springframework/security/expression/support/MethodExpressionVoter.java b/core/src/main/java/org/springframework/security/expression/method/MethodExpressionVoter.java similarity index 96% rename from core/src/main/java/org/springframework/security/expression/support/MethodExpressionVoter.java rename to core/src/main/java/org/springframework/security/expression/method/MethodExpressionVoter.java index 30a1585702..f7c4d5d86b 100644 --- a/core/src/main/java/org/springframework/security/expression/support/MethodExpressionVoter.java +++ b/core/src/main/java/org/springframework/security/expression/method/MethodExpressionVoter.java @@ -1,4 +1,4 @@ -package org.springframework.security.expression.support; +package org.springframework.security.expression.method; import java.util.Collection; import java.util.List; @@ -10,9 +10,9 @@ import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.security.Authentication; import org.springframework.security.ConfigAttribute; -import org.springframework.security.expression.DefaultSecurityExpressionHandler; import org.springframework.security.expression.ExpressionUtils; import org.springframework.security.expression.SecurityExpressionHandler; +import org.springframework.security.expression.support.DefaultSecurityExpressionHandler; import org.springframework.security.vote.AccessDecisionVoter; /** diff --git a/core/src/main/java/org/springframework/security/expression/support/PostInvocationExpressionAttribute.java b/core/src/main/java/org/springframework/security/expression/method/PostInvocationExpressionAttribute.java similarity index 91% rename from core/src/main/java/org/springframework/security/expression/support/PostInvocationExpressionAttribute.java rename to core/src/main/java/org/springframework/security/expression/method/PostInvocationExpressionAttribute.java index db590d927a..c8e7c26ea6 100644 --- a/core/src/main/java/org/springframework/security/expression/support/PostInvocationExpressionAttribute.java +++ b/core/src/main/java/org/springframework/security/expression/method/PostInvocationExpressionAttribute.java @@ -1,4 +1,4 @@ -package org.springframework.security.expression.support; +package org.springframework.security.expression.method; import org.springframework.expression.Expression; import org.springframework.expression.ParseException; diff --git a/core/src/main/java/org/springframework/security/expression/support/PreInvocationExpressionAttribute.java b/core/src/main/java/org/springframework/security/expression/method/PreInvocationExpressionAttribute.java similarity index 94% rename from core/src/main/java/org/springframework/security/expression/support/PreInvocationExpressionAttribute.java rename to core/src/main/java/org/springframework/security/expression/method/PreInvocationExpressionAttribute.java index 56f374a3f1..ef54b67725 100644 --- a/core/src/main/java/org/springframework/security/expression/support/PreInvocationExpressionAttribute.java +++ b/core/src/main/java/org/springframework/security/expression/method/PreInvocationExpressionAttribute.java @@ -1,4 +1,4 @@ -package org.springframework.security.expression.support; +package org.springframework.security.expression.method; import org.springframework.expression.Expression; import org.springframework.expression.ParseException; diff --git a/core/src/main/java/org/springframework/security/expression/DefaultSecurityExpressionHandler.java b/core/src/main/java/org/springframework/security/expression/support/DefaultSecurityExpressionHandler.java similarity index 77% rename from core/src/main/java/org/springframework/security/expression/DefaultSecurityExpressionHandler.java rename to core/src/main/java/org/springframework/security/expression/support/DefaultSecurityExpressionHandler.java index 36e74779c3..aa7e1c619a 100644 --- a/core/src/main/java/org/springframework/security/expression/DefaultSecurityExpressionHandler.java +++ b/core/src/main/java/org/springframework/security/expression/support/DefaultSecurityExpressionHandler.java @@ -1,4 +1,4 @@ -package org.springframework.security.expression; +package org.springframework.security.expression.support; import java.lang.reflect.Array; import java.util.ArrayList; @@ -12,17 +12,19 @@ import org.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; +import org.springframework.expression.spel.standard.StandardEvaluationContext; import org.springframework.security.Authentication; import org.springframework.security.AuthenticationTrustResolver; import org.springframework.security.AuthenticationTrustResolverImpl; +import org.springframework.security.expression.ExpressionUtils; +import org.springframework.security.expression.PermissionEvaluator; +import org.springframework.security.expression.SecurityExpressionHandler; +import org.springframework.security.intercept.web.FilterInvocation; /** - * The standard implementation of SecurityExpressionHandler which uses a {@link SecurityEvaluationContext} - * as the EvaluationContext implementation and configures it with a {@link SecurityExpressionRoot} instance - * as the expression root object. + * The standard implementation of SecurityExpressionHandler. *

- * A single instance should usually be shared between the expression voter and after-invocation provider. - * + * A single instance should usually be shared. * * @author Luke Taylor * @version $Id$ @@ -39,9 +41,13 @@ public class DefaultSecurityExpressionHandler implements SecurityExpressionHandl public DefaultSecurityExpressionHandler() { } + /** + * Uses a {@link MethodSecurityEvaluationContext} as the EvaluationContext implementation and + * configures it with a {@link SecurityExpressionRoot} instance as the expression root object. + */ public EvaluationContext createEvaluationContext(Authentication auth, MethodInvocation mi) { - SecurityEvaluationContext ctx = new SecurityEvaluationContext(auth, mi, parameterNameDiscoverer); - SecurityExpressionRoot root = new SecurityExpressionRoot(auth); + MethodSecurityEvaluationContext ctx = new MethodSecurityEvaluationContext(auth, mi, parameterNameDiscoverer); + MethodSecurityExpressionRoot root = new MethodSecurityExpressionRoot(auth); root.setTrustResolver(trustResolver); root.setPermissionEvaluator(permissionEvaluator); ctx.setRootObject(root); @@ -49,9 +55,15 @@ public class DefaultSecurityExpressionHandler implements SecurityExpressionHandl return ctx; } + public EvaluationContext createEvaluationContext(Authentication authentication, FilterInvocation fi) { + StandardEvaluationContext ctx = new StandardEvaluationContext(); + + return ctx; + } + @SuppressWarnings("unchecked") public Object filter(Object filterTarget, Expression filterExpression, EvaluationContext ctx) { - SecurityExpressionRoot rootObject = (SecurityExpressionRoot) ctx.getRootContextObject(); + MethodSecurityExpressionRoot rootObject = (MethodSecurityExpressionRoot) ctx.getRootContextObject(); List retainList; if (logger.isDebugEnabled()) { @@ -128,6 +140,7 @@ public class DefaultSecurityExpressionHandler implements SecurityExpressionHandl } public void setReturnObject(Object returnObject, EvaluationContext ctx) { - ((SecurityExpressionRoot)ctx.getRootContextObject()).setReturnObject(returnObject); + ((MethodSecurityExpressionRoot)ctx.getRootContextObject()).setReturnObject(returnObject); } + } diff --git a/core/src/main/java/org/springframework/security/expression/DenyAllPermissionEvaluator.java b/core/src/main/java/org/springframework/security/expression/support/DenyAllPermissionEvaluator.java similarity index 85% rename from core/src/main/java/org/springframework/security/expression/DenyAllPermissionEvaluator.java rename to core/src/main/java/org/springframework/security/expression/support/DenyAllPermissionEvaluator.java index d38802dabf..6c07502cce 100644 --- a/core/src/main/java/org/springframework/security/expression/DenyAllPermissionEvaluator.java +++ b/core/src/main/java/org/springframework/security/expression/support/DenyAllPermissionEvaluator.java @@ -1,10 +1,11 @@ -package org.springframework.security.expression; +package org.springframework.security.expression.support; import java.io.Serializable; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.Authentication; +import org.springframework.security.expression.PermissionEvaluator; /** * A null PermissionEvaluator which denies all access. Used by default for situations when permission @@ -14,7 +15,7 @@ import org.springframework.security.Authentication; * @version $Id$ * @since 2.5 */ -public final class DenyAllPermissionEvaluator implements PermissionEvaluator { +class DenyAllPermissionEvaluator implements PermissionEvaluator { private final Log logger = LogFactory.getLog(getClass()); diff --git a/core/src/main/java/org/springframework/security/expression/support/MethodInvocationSecurityExpressionRoot.java b/core/src/main/java/org/springframework/security/expression/support/MethodInvocationSecurityExpressionRoot.java new file mode 100644 index 0000000000..74173ae47b --- /dev/null +++ b/core/src/main/java/org/springframework/security/expression/support/MethodInvocationSecurityExpressionRoot.java @@ -0,0 +1,50 @@ +package org.springframework.security.expression.support; + +import java.io.Serializable; + +import org.springframework.security.Authentication; +import org.springframework.security.expression.PermissionEvaluator; + +public class MethodInvocationSecurityExpressionRoot extends SecurityExpressionRoot { + private PermissionEvaluator permissionEvaluator; + private Object filterObject; + private Object returnObject; + public final String read = "read"; + public final String write = "write"; + public final String create = "create"; + public final String delete = "delete"; + public final String admin = "administration"; + + MethodInvocationSecurityExpressionRoot(Authentication a) { + super(a); + } + + public boolean hasPermission(Object target, Object permission) { + return permissionEvaluator.hasPermission(authentication, target, permission); + } + + public boolean hasPermission(Object targetId, String targetType, Object permission) { + return permissionEvaluator.hasPermission(authentication, (Serializable)targetId, targetType, permission); + } + + public void setFilterObject(Object filterObject) { + this.filterObject = filterObject; + } + + public Object getFilterObject() { + return filterObject; + } + + public void setReturnObject(Object returnObject) { + this.returnObject = returnObject; + } + + public Object getReturnObject() { + return returnObject; + } + + public void setPermissionEvaluator(PermissionEvaluator permissionEvaluator) { + this.permissionEvaluator = permissionEvaluator; + } + +} diff --git a/core/src/main/java/org/springframework/security/expression/SecurityEvaluationContext.java b/core/src/main/java/org/springframework/security/expression/support/MethodSecurityEvaluationContext.java similarity index 87% rename from core/src/main/java/org/springframework/security/expression/SecurityEvaluationContext.java rename to core/src/main/java/org/springframework/security/expression/support/MethodSecurityEvaluationContext.java index 979f36a566..3d2e7e4686 100644 --- a/core/src/main/java/org/springframework/security/expression/SecurityEvaluationContext.java +++ b/core/src/main/java/org/springframework/security/expression/support/MethodSecurityEvaluationContext.java @@ -1,4 +1,4 @@ -package org.springframework.security.expression; +package org.springframework.security.expression.support; import java.lang.reflect.Method; @@ -17,7 +17,7 @@ import org.springframework.util.ClassUtils; * @author Luke Taylor * @since 2.5 */ -public class SecurityEvaluationContext extends StandardEvaluationContext { +class MethodSecurityEvaluationContext extends StandardEvaluationContext { private ParameterNameDiscoverer parameterNameDiscoverer; private boolean argumentsAdded; private MethodInvocation mi; @@ -27,11 +27,11 @@ public class SecurityEvaluationContext extends StandardEvaluationContext { * for each instance. Use the constructor which takes the resolver, as an argument thus * allowing for caching. */ - public SecurityEvaluationContext(Authentication user, MethodInvocation mi) { + public MethodSecurityEvaluationContext(Authentication user, MethodInvocation mi) { this(user, mi, new LocalVariableTableParameterNameDiscoverer()); } - public SecurityEvaluationContext(Authentication user, MethodInvocation mi, + public MethodSecurityEvaluationContext(Authentication user, MethodInvocation mi, ParameterNameDiscoverer parameterNameDiscoverer) { this.mi = mi; this.parameterNameDiscoverer = parameterNameDiscoverer; diff --git a/core/src/main/java/org/springframework/security/expression/support/MethodSecurityExpressionRoot.java b/core/src/main/java/org/springframework/security/expression/support/MethodSecurityExpressionRoot.java new file mode 100644 index 0000000000..b061e50237 --- /dev/null +++ b/core/src/main/java/org/springframework/security/expression/support/MethodSecurityExpressionRoot.java @@ -0,0 +1,58 @@ +package org.springframework.security.expression.support; + +import java.io.Serializable; + +import org.springframework.security.Authentication; +import org.springframework.security.expression.PermissionEvaluator; + + +/** + * Extended expression root object which contains extra method-specific functionality. + * + * @author Luke Taylor + * @version $Id$ + * @since 2.5 + */ +class MethodSecurityExpressionRoot extends SecurityExpressionRoot { + private PermissionEvaluator permissionEvaluator; + private Object filterObject; + private Object returnObject; + public final String read = "read"; + public final String write = "write"; + public final String create = "create"; + public final String delete = "delete"; + public final String admin = "administration"; + + MethodSecurityExpressionRoot(Authentication a) { + super(a); + } + + public boolean hasPermission(Object target, Object permission) { + return permissionEvaluator.hasPermission(authentication, target, permission); + } + + public boolean hasPermission(Object targetId, String targetType, Object permission) { + return permissionEvaluator.hasPermission(authentication, (Serializable)targetId, targetType, permission); + } + + public void setFilterObject(Object filterObject) { + this.filterObject = filterObject; + } + + public Object getFilterObject() { + return filterObject; + } + + public void setReturnObject(Object returnObject) { + this.returnObject = returnObject; + } + + public Object getReturnObject() { + return returnObject; + } + + public void setPermissionEvaluator(PermissionEvaluator permissionEvaluator) { + this.permissionEvaluator = permissionEvaluator; + } + +} diff --git a/core/src/main/java/org/springframework/security/expression/SecurityExpressionRoot.java b/core/src/main/java/org/springframework/security/expression/support/SecurityExpressionRoot.java similarity index 55% rename from core/src/main/java/org/springframework/security/expression/SecurityExpressionRoot.java rename to core/src/main/java/org/springframework/security/expression/support/SecurityExpressionRoot.java index 25a8c9d81a..929bbe5a84 100644 --- a/core/src/main/java/org/springframework/security/expression/SecurityExpressionRoot.java +++ b/core/src/main/java/org/springframework/security/expression/support/SecurityExpressionRoot.java @@ -1,6 +1,5 @@ -package org.springframework.security.expression; +package org.springframework.security.expression.support; -import java.io.Serializable; import java.util.Set; import org.springframework.security.Authentication; @@ -10,32 +9,21 @@ import org.springframework.security.util.AuthorityUtils; /** - * Default root object for use in Spring Security expression evaluations. + * Base root object for use in Spring Security expression evaluations. * * @author Luke Taylor * @version $Id$ * @since 2.5 */ -public class SecurityExpressionRoot { - private Authentication authentication; +abstract class SecurityExpressionRoot { + protected final Authentication authentication; private AuthenticationTrustResolver trustResolver; - private PermissionEvaluator permissionEvaluator; - private Object filterObject; - private Object returnObject; - /** Allows "permitAll" expression */ public final boolean permitAll = true; /** Allows "denyAll" expression */ public final boolean denyAll = false; - public final String read = "read"; - public final String write = "write"; - public final String create = "create"; - public final String delete = "delete"; - public final String admin = "administration"; - - SecurityExpressionRoot(Authentication a) { if (a == null) { throw new IllegalArgumentException("Authentication object cannot be null"); @@ -54,7 +42,7 @@ public class SecurityExpressionRoot { } public final boolean hasAnyRole(String... roles) { - Set roleSet = AuthorityUtils.authorityArrayToSet(authentication.getAuthorities()); + Set roleSet = AuthorityUtils.authorityArrayToSet(authentication.getAuthorities()); for (String role : roles) { if (roleSet.contains(role)) { @@ -65,6 +53,10 @@ public class SecurityExpressionRoot { return false; } + public final Authentication getAuthentication() { + return authentication; + } + public final boolean permitAll() { return true; } @@ -85,45 +77,11 @@ public class SecurityExpressionRoot { return !trustResolver.isAnonymous(authentication) && !trustResolver.isRememberMe(authentication); } - public boolean hasPermission(Object target, Object permission) { - return permissionEvaluator.hasPermission(authentication, target, permission); - } - - public boolean hasPermission(Object targetId, String targetType, Object permission) { - return permissionEvaluator.hasPermission(authentication, (Serializable)targetId, targetType, permission); - } - - public Authentication getAuthentication() { - return authentication; - } - - public void setFilterObject(Object filterObject) { - this.filterObject = filterObject; - } - - public Object getFilterObject() { - return filterObject; - } - - public void setReturnObject(Object returnObject) { - this.returnObject = returnObject; - } - - public Object getReturnObject() { - return returnObject; - } - public Object getPrincipal() { return authentication.getPrincipal(); } - public void setPermissionEvaluator(PermissionEvaluator permissionEvaluator) { - this.permissionEvaluator = permissionEvaluator; - } - public void setTrustResolver(AuthenticationTrustResolver trustResolver) { this.trustResolver = trustResolver; } - - } diff --git a/core/src/main/java/org/springframework/security/expression/support/WebExpressionVoter.java b/core/src/main/java/org/springframework/security/expression/support/WebExpressionVoter.java deleted file mode 100644 index 757a225154..0000000000 --- a/core/src/main/java/org/springframework/security/expression/support/WebExpressionVoter.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.springframework.security.expression.support; - -import java.util.List; - -import org.springframework.security.Authentication; -import org.springframework.security.ConfigAttribute; -import org.springframework.security.intercept.web.FilterInvocation; -import org.springframework.security.vote.AccessDecisionVoter; - -public class WebExpressionVoter implements AccessDecisionVoter { - - public boolean supports(ConfigAttribute attribute) { - return false; - } - - public boolean supports(Class clazz) { - return clazz.isAssignableFrom(FilterInvocation.class); - } - - public int vote(Authentication authentication, Object object, - List attributes) { - // TODO Auto-generated method stub - return 0; - } - -} diff --git a/core/src/main/java/org/springframework/security/expression/support/WebExpressionConfigAttribute.java b/core/src/main/java/org/springframework/security/expression/web/WebExpressionConfigAttribute.java similarity index 74% rename from core/src/main/java/org/springframework/security/expression/support/WebExpressionConfigAttribute.java rename to core/src/main/java/org/springframework/security/expression/web/WebExpressionConfigAttribute.java index e85911091d..103027340b 100644 --- a/core/src/main/java/org/springframework/security/expression/support/WebExpressionConfigAttribute.java +++ b/core/src/main/java/org/springframework/security/expression/web/WebExpressionConfigAttribute.java @@ -1,11 +1,18 @@ -package org.springframework.security.expression.support; +package org.springframework.security.expression.web; import org.springframework.expression.Expression; import org.springframework.expression.ParseException; import org.springframework.expression.spel.SpelExpressionParser; import org.springframework.security.ConfigAttribute; -public class WebExpressionConfigAttribute implements ConfigAttribute { +/** + * Simple expression configuration attribute for use in web request authorizations. + * + * @author Luke Taylor + * @version $Id$ + * @since 2.5 + */ +class WebExpressionConfigAttribute implements ConfigAttribute { private final Expression authorizeExpression; public WebExpressionConfigAttribute(String authorizeExpression) throws ParseException { diff --git a/core/src/main/java/org/springframework/security/expression/web/WebExpressionVoter.java b/core/src/main/java/org/springframework/security/expression/web/WebExpressionVoter.java new file mode 100644 index 0000000000..c64ca347c3 --- /dev/null +++ b/core/src/main/java/org/springframework/security/expression/web/WebExpressionVoter.java @@ -0,0 +1,59 @@ +package org.springframework.security.expression.web; + +import java.util.List; + +import org.aopalliance.intercept.MethodInvocation; +import org.springframework.expression.EvaluationContext; +import org.springframework.security.Authentication; +import org.springframework.security.ConfigAttribute; +import org.springframework.security.expression.SecurityExpressionHandler; +import org.springframework.security.expression.support.DefaultSecurityExpressionHandler; +import org.springframework.security.intercept.web.FilterInvocation; +import org.springframework.security.vote.AccessDecisionVoter; + +/** + * Voter which handles web authorisation decisions. + * @author Luke Taylor + * @version $Id$ + * @since + */ +public class WebExpressionVoter implements AccessDecisionVoter { + private SecurityExpressionHandler expressionHandler = new DefaultSecurityExpressionHandler(); + + public int vote(Authentication authentication, Object object, List attributes) { + WebExpressionConfigAttribute weca = findConfigAttribute(attributes); + + if (weca == null) { + return ACCESS_ABSTAIN; + } + + FilterInvocation fi = (FilterInvocation)object; + EvaluationContext ctx = expressionHandler.createEvaluationContext(authentication, fi); + + + weca.getAuthorizeExpression(); + + return 0; + } + + private WebExpressionConfigAttribute findConfigAttribute(List attributes) { + for (ConfigAttribute attribute : attributes) { + if (attribute instanceof WebExpressionConfigAttribute) { + return (WebExpressionConfigAttribute)attribute; + } + } + return null; + } + + public boolean supports(ConfigAttribute attribute) { + return attribute instanceof WebExpressionConfigAttribute; + } + + public boolean supports(Class clazz) { + return clazz.isAssignableFrom(FilterInvocation.class); + } + + public void setExpressionHandler(SecurityExpressionHandler expressionHandler) { + this.expressionHandler = expressionHandler; + } +} diff --git a/core/src/main/java/org/springframework/security/util/AuthorityUtils.java b/core/src/main/java/org/springframework/security/util/AuthorityUtils.java index 9897703c8c..33a305b662 100644 --- a/core/src/main/java/org/springframework/security/util/AuthorityUtils.java +++ b/core/src/main/java/org/springframework/security/util/AuthorityUtils.java @@ -17,7 +17,7 @@ import java.util.Set; * @version $Id$ */ public abstract class AuthorityUtils { - public static final List NO_AUTHORITIES = Collections.EMPTY_LIST; + public static final List NO_AUTHORITIES = Collections.emptyList(); /** * Returns true if the current user has the specified authority. @@ -76,8 +76,8 @@ public abstract class AuthorityUtils { * Converts an array of GrantedAuthority objects to a Set. * @return a Set of the Strings obtained from each call to GrantedAuthority.getAuthority() */ - public static Set authorityArrayToSet(List authorities) { - Set set = new HashSet(authorities.size()); + public static Set authorityArrayToSet(List authorities) { + Set set = new HashSet(authorities.size()); for (GrantedAuthority authority: authorities) { set.add(authority.getAuthority()); diff --git a/core/src/test/java/org/springframework/security/config/GlobalMethodSecurityBeanDefinitionParserTests.java b/core/src/test/java/org/springframework/security/config/GlobalMethodSecurityBeanDefinitionParserTests.java index 7195ae5512..4bbc6272f8 100644 --- a/core/src/test/java/org/springframework/security/config/GlobalMethodSecurityBeanDefinitionParserTests.java +++ b/core/src/test/java/org/springframework/security/config/GlobalMethodSecurityBeanDefinitionParserTests.java @@ -15,8 +15,8 @@ import org.springframework.security.AuthenticationCredentialsNotFoundException; import org.springframework.security.afterinvocation.AfterInvocationProviderManager; import org.springframework.security.annotation.BusinessService; import org.springframework.security.context.SecurityContextHolder; -import org.springframework.security.expression.support.MethodExpressionAfterInvocationProvider; -import org.springframework.security.expression.support.MethodExpressionVoter; +import org.springframework.security.expression.method.MethodExpressionAfterInvocationProvider; +import org.springframework.security.expression.method.MethodExpressionVoter; import org.springframework.security.providers.TestingAuthenticationToken; import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.springframework.security.userdetails.UserDetailsService; diff --git a/core/src/test/java/org/springframework/security/expression/support/ExpressionAnnotationMethodDefinitionSourceTests.java b/core/src/test/java/org/springframework/security/expression/method/ExpressionAnnotationMethodDefinitionSourceTests.java similarity index 95% rename from core/src/test/java/org/springframework/security/expression/support/ExpressionAnnotationMethodDefinitionSourceTests.java rename to core/src/test/java/org/springframework/security/expression/method/ExpressionAnnotationMethodDefinitionSourceTests.java index 68e4b0a81c..9888642b32 100644 --- a/core/src/test/java/org/springframework/security/expression/support/ExpressionAnnotationMethodDefinitionSourceTests.java +++ b/core/src/test/java/org/springframework/security/expression/method/ExpressionAnnotationMethodDefinitionSourceTests.java @@ -1,4 +1,4 @@ -package org.springframework.security.expression.support; +package org.springframework.security.expression.method; import static org.junit.Assert.*; @@ -11,6 +11,9 @@ import org.springframework.security.expression.annotation.PostAuthorize; import org.springframework.security.expression.annotation.PostFilter; import org.springframework.security.expression.annotation.PreAuthorize; import org.springframework.security.expression.annotation.PreFilter; +import org.springframework.security.expression.method.ExpressionAnnotationMethodDefinitionSource; +import org.springframework.security.expression.method.PostInvocationExpressionAttribute; +import org.springframework.security.expression.method.PreInvocationExpressionAttribute; import org.springframework.security.intercept.method.MockMethodInvocation; diff --git a/core/src/test/java/org/springframework/security/expression/support/MethodExpressionVoterTests.java b/core/src/test/java/org/springframework/security/expression/method/MethodExpressionVoterTests.java similarity index 94% rename from core/src/test/java/org/springframework/security/expression/support/MethodExpressionVoterTests.java rename to core/src/test/java/org/springframework/security/expression/method/MethodExpressionVoterTests.java index a4099db637..ec803e7a57 100644 --- a/core/src/test/java/org/springframework/security/expression/support/MethodExpressionVoterTests.java +++ b/core/src/test/java/org/springframework/security/expression/method/MethodExpressionVoterTests.java @@ -1,4 +1,4 @@ -package org.springframework.security.expression.support; +package org.springframework.security.expression.method; import static org.junit.Assert.assertEquals; @@ -11,6 +11,8 @@ import java.util.List; import org.aopalliance.intercept.MethodInvocation; import org.junit.Test; import org.springframework.security.ConfigAttribute; +import org.springframework.security.expression.method.MethodExpressionVoter; +import org.springframework.security.expression.method.PreInvocationExpressionAttribute; import org.springframework.security.providers.TestingAuthenticationToken; import org.springframework.security.util.SimpleMethodInvocation; import org.springframework.security.vote.AccessDecisionVoter; @@ -83,7 +85,7 @@ public class MethodExpressionVoterTests { public void ruleDefinedInAClassMethodIsApplied() throws Exception { MethodInvocation mi = new SimpleMethodInvocation(new TargetImpl(), methodTakingAString(), "joe"); assertEquals(AccessDecisionVoter.ACCESS_GRANTED, am.vote(joe, mi, - createAttributes(new PreInvocationExpressionAttribute(null, null, "new org.springframework.security.expression.support.SecurityRules().isJoe(#argument)")))); + createAttributes(new PreInvocationExpressionAttribute(null, null, "new org.springframework.security.expression.method.SecurityRules().isJoe(#argument)")))); } private List createAttributes(ConfigAttribute... attributes) { @@ -132,6 +134,4 @@ public class MethodExpressionVoterTests { public Collection methodTakingACollection(Collection collection) {return collection;} } - - } diff --git a/core/src/test/java/org/springframework/security/expression/support/SecurityRules.java b/core/src/test/java/org/springframework/security/expression/method/SecurityRules.java similarity index 81% rename from core/src/test/java/org/springframework/security/expression/support/SecurityRules.java rename to core/src/test/java/org/springframework/security/expression/method/SecurityRules.java index 3045ffe6f5..f1b7e81c22 100644 --- a/core/src/test/java/org/springframework/security/expression/support/SecurityRules.java +++ b/core/src/test/java/org/springframework/security/expression/method/SecurityRules.java @@ -1,4 +1,4 @@ -package org.springframework.security.expression.support; +package org.springframework.security.expression.method; public class SecurityRules { public static boolean disallow() { diff --git a/core/src/test/java/org/springframework/security/expression/SecurityExpressionRootTests.java b/core/src/test/java/org/springframework/security/expression/support/MethodSecurityExpressionRootTests.java similarity index 91% rename from core/src/test/java/org/springframework/security/expression/SecurityExpressionRootTests.java rename to core/src/test/java/org/springframework/security/expression/support/MethodSecurityExpressionRootTests.java index 019f8dbdb5..c6ac30ef45 100644 --- a/core/src/test/java/org/springframework/security/expression/SecurityExpressionRootTests.java +++ b/core/src/test/java/org/springframework/security/expression/support/MethodSecurityExpressionRootTests.java @@ -1,4 +1,4 @@ -package org.springframework.security.expression; +package org.springframework.security.expression.support; import static org.junit.Assert.*; @@ -11,18 +11,18 @@ import org.springframework.expression.spel.SpelExpressionParser; import org.springframework.expression.spel.standard.StandardEvaluationContext; import org.springframework.security.Authentication; import org.springframework.security.AuthenticationTrustResolver; -import org.springframework.security.expression.SecurityExpressionRoot; - +import org.springframework.security.expression.ExpressionUtils; +import org.springframework.security.expression.PermissionEvaluator; /** - * Sandbox class for checking feasibility of different security-related expressions. + * Tests for {@link MethodSecurityExpressionRoot} * * @author Luke Taylor * @version $Id$ */ -public class SecurityExpressionRootTests { +public class MethodSecurityExpressionRootTests { SpelExpressionParser parser = new SpelExpressionParser(); - SecurityExpressionRoot root; + MethodSecurityExpressionRoot root; StandardEvaluationContext ctx; Mockery jmock = new Mockery(); private AuthenticationTrustResolver trustResolver; @@ -32,7 +32,7 @@ public class SecurityExpressionRootTests { @Before public void createContext() { user = jmock.mock(Authentication.class); - root = new SecurityExpressionRoot(user); + root = new MethodSecurityExpressionRoot(user); ctx = new StandardEvaluationContext(); ctx.setRootObject(root); trustResolver = jmock.mock(AuthenticationTrustResolver.class);