소스 검색

SEC-170: AbstractAclVoter to support JoinPoint.

Ben Alex 19 년 전
부모
커밋
ca1bf5cc21

+ 42 - 25
core/src/main/java/org/acegisecurity/vote/AbstractAclVoter.java

@@ -1,4 +1,4 @@
-/* Copyright 2004, 2005 Acegi Technology Pty Limited
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,11 +17,15 @@ package org.acegisecurity.vote;
 
 import org.acegisecurity.AuthorizationServiceException;
 import org.acegisecurity.ConfigAttribute;
+
 import org.acegisecurity.acl.AclEntry;
 import org.acegisecurity.acl.AclManager;
 
 import org.aopalliance.intercept.MethodInvocation;
 
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.reflect.CodeSignature;
+
 import org.springframework.util.Assert;
 
 import java.lang.reflect.Method;
@@ -39,8 +43,7 @@ import java.lang.reflect.Method;
  * <code>Authentication</code> object. This class is designed to process
  * {@link AclEntry}s that are subclasses of {@link
  * org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are
- * obtained by using the {@link
- * org.acegisecurity.acl.basic.BasicAclProvider}.
+ * obtained by using the {@link org.acegisecurity.acl.basic.BasicAclProvider}.
  * </p>
  * 
  * <p>
@@ -122,16 +125,42 @@ public abstract class AbstractAclVoter implements AccessDecisionVoter {
 
     //~ Methods ================================================================
 
-    public void setProcessDomainObjectClass(Class processDomainObjectClass) {
-        Assert.notNull(processDomainObjectClass,
-            "processDomainObjectClass cannot be set to null");
-        this.processDomainObjectClass = processDomainObjectClass;
+    protected Object getDomainObjectInstance(Object secureObject) {
+        Object[] args;
+        Class[] params;
+
+        if (secureObject instanceof MethodInvocation) {
+            MethodInvocation invocation = (MethodInvocation) secureObject;
+            params = invocation.getMethod().getParameterTypes();
+            args = invocation.getArguments();
+        } else {
+            JoinPoint jp = (JoinPoint) secureObject;
+            params = ((CodeSignature) jp.getStaticPart().getSignature())
+                .getParameterTypes();
+            args = jp.getArgs();
+        }
+
+        for (int i = 0; i < params.length; i++) {
+            if (processDomainObjectClass.isAssignableFrom(params[i])) {
+                return args[i];
+            }
+        }
+
+        throw new AuthorizationServiceException("Secure object: "
+            + secureObject + " did not provide any argument of type: "
+            + processDomainObjectClass);
     }
 
     public Class getProcessDomainObjectClass() {
         return processDomainObjectClass;
     }
 
+    public void setProcessDomainObjectClass(Class processDomainObjectClass) {
+        Assert.notNull(processDomainObjectClass,
+            "processDomainObjectClass cannot be set to null");
+        this.processDomainObjectClass = processDomainObjectClass;
+    }
+
     /**
      * This implementation supports only
      * <code>MethodSecurityInterceptor</code>, because it queries the
@@ -143,24 +172,12 @@ public abstract class AbstractAclVoter implements AccessDecisionVoter {
      *         <code>MethodInvocation</code>, <code>false</code> otherwise
      */
     public boolean supports(Class clazz) {
-        return (MethodInvocation.class.isAssignableFrom(clazz));
-    }
-
-    protected Object getDomainObjectInstance(Object secureObject) {
-        MethodInvocation invocation = (MethodInvocation) secureObject;
-
-        // Check if this MethodInvocation provides the required argument
-        Method method = invocation.getMethod();
-        Class[] params = method.getParameterTypes();
-
-        for (int i = 0; i < params.length; i++) {
-            if (processDomainObjectClass.isAssignableFrom(params[i])) {
-                return invocation.getArguments()[i];
-            }
+        if (MethodInvocation.class.isAssignableFrom(clazz)) {
+            return true;
+        } else if (JoinPoint.class.isAssignableFrom(clazz)) {
+            return true;
+        } else {
+            return false;
         }
-
-        throw new AuthorizationServiceException("MethodInvocation: "
-            + invocation + " did not provide any argument of type: "
-            + processDomainObjectClass);
     }
 }

+ 18 - 14
core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java

@@ -1,4 +1,4 @@
-/* Copyright 2004, 2005 Acegi Technology Pty Limited
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,11 +21,14 @@ import org.acegisecurity.AuthorizationServiceException;
 import org.acegisecurity.ConfigAttributeDefinition;
 import org.acegisecurity.MockAclManager;
 import org.acegisecurity.SecurityConfig;
+
 import org.acegisecurity.acl.AclEntry;
 import org.acegisecurity.acl.AclManager;
 import org.acegisecurity.acl.basic.MockAclObjectIdentity;
 import org.acegisecurity.acl.basic.SimpleAclEntry;
+
 import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
+
 import org.acegisecurity.util.SimpleMethodInvocation;
 
 import org.aopalliance.intercept.MethodInvocation;
@@ -54,14 +57,23 @@ public class BasicAclEntryVoterTests extends TestCase {
 
     //~ Methods ================================================================
 
-    public final void setUp() throws Exception {
-        super.setUp();
+    private MethodInvocation getMethodInvocation(SomeDomainObject domainObject)
+        throws Exception {
+        Class clazz = SomeDomainObjectManager.class;
+        Method method = clazz.getMethod("someServiceMethod",
+                new Class[] {SomeDomainObject.class});
+
+        return new SimpleMethodInvocation(method, new Object[] {domainObject});
     }
 
     public static void main(String[] args) {
         junit.textui.TestRunner.run(BasicAclEntryVoterTests.class);
     }
 
+    public final void setUp() throws Exception {
+        super.setUp();
+    }
+
     public void testNormalOperation() throws Exception {
         // Setup a domain object subject of this test
         SomeDomainObject domainObject = new SomeDomainObject("foo");
@@ -101,10 +113,11 @@ public class BasicAclEntryVoterTests extends TestCase {
                 attr));
     }
 
-    public void testOnlySupportsMethodInvocation() {
+    public void testOnlySupportsMethodInvocationAndJoinPoint() {
         BasicAclEntryVoter voter = new BasicAclEntryVoter();
         assertTrue(voter.supports(MethodInvocation.class));
-        assertFalse(voter.supports(JoinPoint.class));
+        assertTrue(voter.supports(JoinPoint.class));
+        assertFalse(voter.supports(String.class));
     }
 
     public void testStartupRejectsMissingAclManager() throws Exception {
@@ -456,15 +469,6 @@ public class BasicAclEntryVoterTests extends TestCase {
         }
     }
 
-    private MethodInvocation getMethodInvocation(SomeDomainObject domainObject)
-        throws Exception {
-        Class clazz = SomeDomainObjectManager.class;
-        Method method = clazz.getMethod("someServiceMethod",
-                new Class[] {SomeDomainObject.class});
-
-        return new SimpleMethodInvocation(method, new Object[] {domainObject});
-    }
-
     //~ Inner Classes ==========================================================
 
     private class MockAclEntry implements AclEntry {