Procházet zdrojové kódy

SEC-1576: Parameterize the secured object type in AccessDecisionVoter.

Luke Taylor před 14 roky
rodič
revize
c8820166c8

+ 1 - 0
acl/acl.gradle

@@ -2,6 +2,7 @@
 
 dependencies {
     compile project(':spring-security-core'),
+            'aopalliance:aopalliance:1.0',
             "net.sf.ehcache:ehcache:$ehcacheVersion",
             "org.springframework:spring-aop:$springVersion",
             "org.springframework:spring-context:$springVersion",

+ 2 - 1
acl/src/main/java/org/springframework/security/acls/AclEntryVoter.java

@@ -20,6 +20,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 
+import org.aopalliance.intercept.MethodInvocation;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.springframework.security.access.AuthorizationServiceException;
@@ -148,7 +149,7 @@ public class AclEntryVoter extends AbstractAclVoter {
         return (attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute());
     }
 
-    public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
+    public int vote(Authentication authentication, MethodInvocation object, Collection<ConfigAttribute> attributes) {
 
         for(ConfigAttribute attr : attributes) {
 

+ 24 - 25
core/src/main/java/org/springframework/security/access/AccessDecisionVoter.java

@@ -22,16 +22,14 @@ import org.springframework.security.core.Authentication;
 
 /**
  * Indicates a class is responsible for voting on authorization decisions.
- *
  * <p>
- * The coordination of voting (ie polling <code>AccessDecisionVoter</code>s,
+ * The coordination of voting (ie polling {@code AccessDecisionVoter}s,
  * tallying their responses, and making the final authorization decision) is
  * performed by an {@link org.springframework.security.access.AccessDecisionManager}.
- * </p>
  *
  * @author Ben Alex
  */
-public interface AccessDecisionVoter {
+public interface AccessDecisionVoter<S> {
     //~ Static fields/initializers =====================================================================================
 
     int ACCESS_GRANTED = 1;
@@ -41,20 +39,20 @@ public interface AccessDecisionVoter {
     //~ Methods ========================================================================================================
 
     /**
-     * Indicates whether this <code>AccessDecisionVoter</code> is able to vote on the passed
-     * <code>ConfigAttribute</code>.<p>This allows the <code>AbstractSecurityInterceptor</code> to check every
-     * configuration attribute can be consumed by the configured <code>AccessDecisionManager</code> and/or
-     * <code>RunAsManager</code> and/or <code>AfterInvocationManager</code>.</p>
+     * Indicates whether this {@code AccessDecisionVoter} is able to vote on the passed {@code ConfigAttribute}.
+     * <p>
+     * This allows the {@code AbstractSecurityInterceptor} to check every configuration attribute can be consumed by
+     * the configured {@code AccessDecisionManager} and/or {@code RunAsManager} and/or {@code AfterInvocationManager}.
      *
      * @param attribute a configuration attribute that has been configured against the
-     *        <code>AbstractSecurityInterceptor</code>
+     *        {@code AbstractSecurityInterceptor}
      *
-     * @return true if this <code>AccessDecisionVoter</code> can support the passed configuration attribute
+     * @return true if this {@code AccessDecisionVoter} can support the passed configuration attribute
      */
     boolean supports(ConfigAttribute attribute);
 
     /**
-     * Indicates whether the <code>AccessDecisionVoter</code> implementation is able to provide access control
+     * Indicates whether the {@code AccessDecisionVoter} implementation is able to provide access control
      * votes for the indicated secured object type.
      *
      * @param clazz the class that is being queried
@@ -65,26 +63,27 @@ public interface AccessDecisionVoter {
 
     /**
      * Indicates whether or not access is granted.
-     * <p>The decision must be affirmative (<code>ACCESS_GRANTED</code>), negative (<code>ACCESS_DENIED</code>)
-     * or the <code>AccessDecisionVoter</code> can abstain (<code>ACCESS_ABSTAIN</code>) from voting.
+     * <p>
+     * The decision must be affirmative ({@code ACCESS_GRANTED}), negative ({@code ACCESS_DENIED})
+     * or the {@code AccessDecisionVoter} can abstain ({@code ACCESS_ABSTAIN}) from voting.
      * Under no circumstances should implementing classes return any other value. If a weighting of results is desired,
      * this should be handled in a custom {@link org.springframework.security.access.AccessDecisionManager} instead.
-     * </p>
-     * <p>Unless an <code>AccessDecisionVoter</code> is specifically intended to vote on an access control
+     * <p>
+     * Unless an {@code AccessDecisionVoter} is specifically intended to vote on an access control
      * decision due to a passed method invocation or configuration attribute parameter, it must return
-     * <code>ACCESS_ABSTAIN</code>. This prevents the coordinating <code>AccessDecisionManager</code> from counting
-     * votes from those <code>AccessDecisionVoter</code>s without a legitimate interest in the access control
+     * {@code ACCESS_ABSTAIN}. This prevents the coordinating {@code AccessDecisionManager} from counting
+     * votes from those {@code AccessDecisionVoter}s without a legitimate interest in the access control
      * decision.
-     * </p>
-     * <p>Whilst the method invocation is passed as a parameter to maximise flexibility in making access
-     * control decisions, implementing classes must never modify the behaviour of the method invocation (such as
-     * calling <Code>MethodInvocation.proceed()</code>).</p>
+     * <p>
+     * Whilst the secured object (such as a {@code MethodInvocation}) is passed as a parameter to maximise flexibility
+     * in making access control decisions, implementing classes should not modify it or cause the represented invocation
+     * to take place (for example, by calling {@code MethodInvocation.proceed()}).
      *
-     * @param authentication the caller invoking the method
-     * @param object the secured object
-     * @param attributes the configuration attributes associated with the method being invoked
+     * @param authentication the caller making the invocation
+     * @param object the secured object being invoked
+     * @param attributes the configuration attributes associated with the secured object
      *
      * @return either {@link #ACCESS_GRANTED}, {@link #ACCESS_ABSTAIN} or {@link #ACCESS_DENIED}
      */
-    int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes);
+    int vote(Authentication authentication, S object, Collection<ConfigAttribute> attributes);
 }

+ 1 - 1
core/src/main/java/org/springframework/security/access/annotation/Jsr250Voter.java

@@ -13,7 +13,7 @@ import org.springframework.security.core.GrantedAuthority;
  * @author Ryan Heaton
  * @since 2.0
  */
-public class Jsr250Voter implements AccessDecisionVoter {
+public class Jsr250Voter implements AccessDecisionVoter<Object> {
 
     /**
      * The specified config attribute is supported if its an instance of a {@link Jsr250SecurityConfig}.

+ 3 - 3
core/src/main/java/org/springframework/security/access/prepost/PreInvocationAuthorizationAdviceVoter.java

@@ -21,7 +21,7 @@ import org.springframework.security.core.Authentication;
  * @author Luke Taylor
  * @since 3.0
  */
-public class PreInvocationAuthorizationAdviceVoter implements AccessDecisionVoter {
+public class PreInvocationAuthorizationAdviceVoter implements AccessDecisionVoter<MethodInvocation> {
     protected final Log logger = LogFactory.getLog(getClass());
 
     private final PreInvocationAuthorizationAdvice preAdvice;
@@ -38,7 +38,7 @@ public class PreInvocationAuthorizationAdviceVoter implements AccessDecisionVote
         return clazz.isAssignableFrom(MethodInvocation.class);
     }
 
-    public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
+    public int vote(Authentication authentication, MethodInvocation method, Collection<ConfigAttribute> attributes) {
 
         // Find prefilter and preauth (or combined) attributes
         // if both null, abstain
@@ -51,7 +51,7 @@ public class PreInvocationAuthorizationAdviceVoter implements AccessDecisionVote
             return ACCESS_ABSTAIN;
         }
 
-        boolean allowed = preAdvice.before(authentication, (MethodInvocation)object, preAttr);
+        boolean allowed = preAdvice.before(authentication, method, preAttr);
 
         return allowed ? ACCESS_GRANTED : ACCESS_DENIED;
     }

+ 3 - 4
core/src/main/java/org/springframework/security/access/vote/AbstractAclVoter.java

@@ -26,18 +26,17 @@ import org.springframework.util.Assert;
  *
  * @author Ben Alex
  */
-public abstract class AbstractAclVoter implements AccessDecisionVoter {
+public abstract class AbstractAclVoter implements AccessDecisionVoter<MethodInvocation> {
     //~ Instance fields ================================================================================================
 
     private Class<?> processDomainObjectClass;
 
     //~ Methods ========================================================================================================
 
-    protected Object getDomainObjectInstance(Object secureObject) {
+    protected Object getDomainObjectInstance(MethodInvocation invocation) {
         Object[] args;
         Class<?>[] params;
 
-        MethodInvocation invocation = (MethodInvocation) secureObject;
         params = invocation.getMethod().getParameterTypes();
         args = invocation.getArguments();
 
@@ -47,7 +46,7 @@ public abstract class AbstractAclVoter implements AccessDecisionVoter {
             }
         }
 
-        throw new AuthorizationServiceException("Secure object: " + secureObject
+        throw new AuthorizationServiceException("MethodInvocation: " + invocation
             + " did not provide any argument of type: " + processDomainObjectClass);
     }
 

+ 3 - 3
core/src/main/java/org/springframework/security/access/vote/AuthenticatedVoter.java

@@ -41,7 +41,7 @@ import org.springframework.util.Assert;
  *
  * @author Ben Alex
  */
-public class AuthenticatedVoter implements AccessDecisionVoter {
+public class AuthenticatedVoter implements AccessDecisionVoter<Object> {
     //~ Static fields/initializers =====================================================================================
 
     public static final String IS_AUTHENTICATED_FULLY = "IS_AUTHENTICATED_FULLY";
@@ -77,9 +77,9 @@ public class AuthenticatedVoter implements AccessDecisionVoter {
     /**
      * This implementation supports any type of class, because it does not query the presented secure object.
      *
-     * @param clazz the secure object
+     * @param clazz the secure object type
      *
-     * @return always <code>true</code>
+     * @return always {@code true}
      */
     public boolean supports(Class<?> clazz) {
         return true;

+ 1 - 1
core/src/main/java/org/springframework/security/access/vote/RoleVoter.java

@@ -49,7 +49,7 @@ import org.springframework.security.core.GrantedAuthority;
  * @author Ben Alex
  * @author colin sampaleanu
  */
-public class RoleVoter implements AccessDecisionVoter {
+public class RoleVoter implements AccessDecisionVoter<Object> {
     //~ Instance fields ================================================================================================
 
     private String rolePrefix = "ROLE_";

+ 1 - 1
core/src/test/java/org/springframework/security/access/vote/AbstractAccessDecisionManagerTests.java

@@ -150,7 +150,7 @@ public class AbstractAccessDecisionManagerTests extends TestCase {
         }
     }
 
-    private class MockStringOnlyVoter implements AccessDecisionVoter {
+    private class MockStringOnlyVoter implements AccessDecisionVoter<Object> {
         public boolean supports(Class<?> clazz) {
             return String.class.isAssignableFrom(clazz);
         }

+ 1 - 1
core/src/test/java/org/springframework/security/access/vote/AbstractAclVoterTests.java

@@ -19,7 +19,7 @@ public class AbstractAclVoterTests {
         public boolean supports(ConfigAttribute attribute) {
             return false;
         }
-        public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
+        public int vote(Authentication authentication, MethodInvocation object, Collection<ConfigAttribute> attributes) {
             return 0;
         }
     };

+ 1 - 1
core/src/test/java/org/springframework/security/access/vote/DenyAgainVoter.java

@@ -32,7 +32,7 @@ import java.util.Iterator;
  *
  * @author Ben Alex
  */
-public class DenyAgainVoter implements AccessDecisionVoter {
+public class DenyAgainVoter implements AccessDecisionVoter<Object> {
     // ~ Methods
     // ========================================================================================================
 

+ 1 - 1
core/src/test/java/org/springframework/security/access/vote/DenyVoter.java

@@ -30,7 +30,7 @@ import java.util.Iterator;
  *
  * @author Ben Alex
  */
-public class DenyVoter implements AccessDecisionVoter {
+public class DenyVoter implements AccessDecisionVoter<Object> {
     //~ Methods ========================================================================================================
 
     public boolean supports(ConfigAttribute attribute) {

+ 3 - 4
web/src/main/java/org/springframework/security/web/access/expression/WebExpressionVoter.java

@@ -15,12 +15,12 @@ import org.springframework.security.web.FilterInvocation;
  * @author Luke Taylor
  * @since 3.0
  */
-public class WebExpressionVoter implements AccessDecisionVoter {
+public class WebExpressionVoter implements AccessDecisionVoter<FilterInvocation> {
     private SecurityExpressionHandler<FilterInvocation> expressionHandler = new DefaultWebSecurityExpressionHandler();
 
-    public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
+    public int vote(Authentication authentication, FilterInvocation fi, Collection<ConfigAttribute> attributes) {
         assert authentication != null;
-        assert object != null;
+        assert fi != null;
         assert attributes != null;
 
         WebExpressionConfigAttribute weca = findConfigAttribute(attributes);
@@ -29,7 +29,6 @@ public class WebExpressionVoter implements AccessDecisionVoter {
             return ACCESS_ABSTAIN;
         }
 
-        FilterInvocation fi = (FilterInvocation)object;
         EvaluationContext ctx = expressionHandler.createEvaluationContext(authentication, fi);
 
         return ExpressionUtils.evaluateAsBoolean(weca.getAuthorizeExpression(), ctx) ?