Bladeren bron

SEC-999: Refactored expression security classes for better separation of concerns and of method vs web authorization expressions.

Luke Taylor 17 jaren geleden
bovenliggende
commit
3acd515c6c
26 gewijzigde bestanden met toevoegingen van 261 en 148 verwijderingen
  1. 1 1
      core/src/main/java/org/springframework/security/config/ConfigUtils.java
  2. 4 4
      core/src/main/java/org/springframework/security/config/GlobalMethodSecurityBeanDefinitionParser.java
  3. 0 7
      core/src/main/java/org/springframework/security/expression/ExpressionUtils.java
  4. 0 11
      core/src/main/java/org/springframework/security/expression/MethodInvocationSecurityExpressionRoot.java
  5. 12 3
      core/src/main/java/org/springframework/security/expression/SecurityExpressionHandler.java
  6. 1 2
      core/src/main/java/org/springframework/security/expression/method/AbstractExpressionBasedMethodConfigAttribute.java
  7. 1 1
      core/src/main/java/org/springframework/security/expression/method/ExpressionAnnotationMethodDefinitionSource.java
  8. 2 2
      core/src/main/java/org/springframework/security/expression/method/MethodExpressionAfterInvocationProvider.java
  9. 2 2
      core/src/main/java/org/springframework/security/expression/method/MethodExpressionVoter.java
  10. 1 1
      core/src/main/java/org/springframework/security/expression/method/PostInvocationExpressionAttribute.java
  11. 1 1
      core/src/main/java/org/springframework/security/expression/method/PreInvocationExpressionAttribute.java
  12. 23 10
      core/src/main/java/org/springframework/security/expression/support/DefaultSecurityExpressionHandler.java
  13. 3 2
      core/src/main/java/org/springframework/security/expression/support/DenyAllPermissionEvaluator.java
  14. 50 0
      core/src/main/java/org/springframework/security/expression/support/MethodInvocationSecurityExpressionRoot.java
  15. 4 4
      core/src/main/java/org/springframework/security/expression/support/MethodSecurityEvaluationContext.java
  16. 58 0
      core/src/main/java/org/springframework/security/expression/support/MethodSecurityExpressionRoot.java
  17. 9 51
      core/src/main/java/org/springframework/security/expression/support/SecurityExpressionRoot.java
  18. 0 26
      core/src/main/java/org/springframework/security/expression/support/WebExpressionVoter.java
  19. 9 2
      core/src/main/java/org/springframework/security/expression/web/WebExpressionConfigAttribute.java
  20. 59 0
      core/src/main/java/org/springframework/security/expression/web/WebExpressionVoter.java
  21. 3 3
      core/src/main/java/org/springframework/security/util/AuthorityUtils.java
  22. 2 2
      core/src/test/java/org/springframework/security/config/GlobalMethodSecurityBeanDefinitionParserTests.java
  23. 4 1
      core/src/test/java/org/springframework/security/expression/method/ExpressionAnnotationMethodDefinitionSourceTests.java
  24. 4 4
      core/src/test/java/org/springframework/security/expression/method/MethodExpressionVoterTests.java
  25. 1 1
      core/src/test/java/org/springframework/security/expression/method/SecurityRules.java
  26. 7 7
      core/src/test/java/org/springframework/security/expression/support/MethodSecurityExpressionRootTests.java

+ 1 - 1
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;

+ 4 - 4
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";
 

+ 0 - 7
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);
         }
     }
-
-
 }

+ 0 - 11
core/src/main/java/org/springframework/security/expression/MethodInvocationSecurityExpressionRoot.java

@@ -1,11 +0,0 @@
-package org.springframework.security.expression;
-
-import org.springframework.security.Authentication;
-
-public class MethodInvocationSecurityExpressionRoot extends SecurityExpressionRoot {
-
-    MethodInvocationSecurityExpressionRoot(Authentication a) {
-        super(a);
-    }
-
-}

+ 12 - 3
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);
 

+ 1 - 2
core/src/main/java/org/springframework/security/expression/support/AbstractExpressionBasedMethodConfigAttribute.java → 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;
     }

+ 1 - 1
core/src/main/java/org/springframework/security/expression/support/ExpressionAnnotationMethodDefinitionSource.java → 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;

+ 2 - 2
core/src/main/java/org/springframework/security/expression/support/MethodExpressionAfterInvocationProvider.java → 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.

+ 2 - 2
core/src/main/java/org/springframework/security/expression/support/MethodExpressionVoter.java → 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;
 
 /**

+ 1 - 1
core/src/main/java/org/springframework/security/expression/support/PostInvocationExpressionAttribute.java → 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;

+ 1 - 1
core/src/main/java/org/springframework/security/expression/support/PreInvocationExpressionAttribute.java → 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;

+ 23 - 10
core/src/main/java/org/springframework/security/expression/DefaultSecurityExpressionHandler.java → 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 <tt>SecurityExpressionHandler</tt> which uses a {@link SecurityEvaluationContext}
- * as the <tt>EvaluationContext</tt> implementation and configures it with a {@link SecurityExpressionRoot} instance
- * as the expression root object.
+ * The standard implementation of <tt>SecurityExpressionHandler</tt>.
  * <p>
- * 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 <tt>EvaluationContext</tt> 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);
     }
+
 }

+ 3 - 2
core/src/main/java/org/springframework/security/expression/DenyAllPermissionEvaluator.java → 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());
 

+ 50 - 0
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;
+    }
+
+}

+ 4 - 4
core/src/main/java/org/springframework/security/expression/SecurityEvaluationContext.java → 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;

+ 58 - 0
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;
+    }
+
+}

+ 9 - 51
core/src/main/java/org/springframework/security/expression/SecurityExpressionRoot.java → 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<String> 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;
     }
-
-
 }

+ 0 - 26
core/src/main/java/org/springframework/security/expression/support/WebExpressionVoter.java

@@ -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<? extends Object> clazz) {
-        return clazz.isAssignableFrom(FilterInvocation.class);
-    }
-
-    public int vote(Authentication authentication, Object object,
-            List<ConfigAttribute> attributes) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-}

+ 9 - 2
core/src/main/java/org/springframework/security/expression/support/WebExpressionConfigAttribute.java → 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 {

+ 59 - 0
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<ConfigAttribute> 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<ConfigAttribute> 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<? extends Object> clazz) {
+        return clazz.isAssignableFrom(FilterInvocation.class);
+    }
+
+    public void setExpressionHandler(SecurityExpressionHandler expressionHandler) {
+        this.expressionHandler = expressionHandler;
+    }
+}

+ 3 - 3
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<GrantedAuthority> NO_AUTHORITIES = Collections.EMPTY_LIST;
+    public static final List<GrantedAuthority> 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<GrantedAuthority> authorities) {
-        Set set = new HashSet(authorities.size());
+    public static Set<String> authorityArrayToSet(List<GrantedAuthority> authorities) {
+        Set<String> set = new HashSet<String>(authorities.size());
 
         for (GrantedAuthority authority: authorities) {
             set.add(authority.getAuthority());

+ 2 - 2
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;

+ 4 - 1
core/src/test/java/org/springframework/security/expression/support/ExpressionAnnotationMethodDefinitionSourceTests.java → 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;
 
 

+ 4 - 4
core/src/test/java/org/springframework/security/expression/support/MethodExpressionVoterTests.java → 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<ConfigAttribute> createAttributes(ConfigAttribute... attributes) {
@@ -132,6 +134,4 @@ public class MethodExpressionVoterTests {
 
         public Collection methodTakingACollection(Collection collection) {return collection;}
     }
-
-
 }

+ 1 - 1
core/src/test/java/org/springframework/security/expression/support/SecurityRules.java → 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() {

+ 7 - 7
core/src/test/java/org/springframework/security/expression/SecurityExpressionRootTests.java → 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);