浏览代码

SEC-274: Correctly handle bridge methods, using AnnotationUtils when on classpath.

Ben Alex 19 年之前
父节点
当前提交
44cae6b2ee

+ 17 - 2
core-tiger/src/main/java/org/acegisecurity/annotation/SecurityAnnotationAttributes.java

@@ -12,13 +12,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.acegisecurity.annotation;
 
 import org.acegisecurity.SecurityConfig;
 
 import org.springframework.metadata.Attributes;
 
+import org.springframework.util.ClassUtils;
+
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
@@ -43,6 +44,8 @@ import java.util.Set;
  * &lt;/bean></pre></p>
  *  <p>These security annotations are similiar to the Commons Attributes approach, however they are using Java 5
  * language-level metadata support.</p>
+ *  <p>This class should be used with Spring 2.0 or above, as it relies upon utility classes in Spring 2.0 for
+ * correct introspection of annotations on bridge methods.</p>
  *
  * @author Mark St.Godard
  * @version $Id$
@@ -96,7 +99,19 @@ public class SecurityAnnotationAttributes implements Attributes {
     public Collection getAttributes(Method method) {
         Set<SecurityConfig> attributes = new HashSet<SecurityConfig>();
 
-        for (Annotation annotation : method.getAnnotations()) {
+        Annotation[] annotations = null;
+
+        // Use AnnotationUtils if in classpath (ie Spring 1.2.9+ deployment)
+        try {
+            Class clazz = ClassUtils.forName("org.springframework.core.annotation.AnnotationUtils");
+            Method m = clazz.getMethod("getAnnotations", new Class[] {Method.class});
+            annotations = (Annotation[]) m.invoke(null, new Object[] {method});
+        } catch (Exception ex) {
+            // Fallback to manual retrieval if no AnnotationUtils available
+            annotations = method.getAnnotations();
+        }
+
+        for (Annotation annotation : annotations) {
             // check for Secured annotations
             if (annotation instanceof Secured) {
                 Secured attr = (Secured) annotation;

+ 68 - 60
core-tiger/src/test/java/org/acegisecurity/annotation/SecurityAnnotationAttributesTests.java

@@ -12,20 +12,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.acegisecurity.annotation;
 
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.Collection;
-
 import junit.framework.TestCase;
 
 import org.acegisecurity.SecurityConfig;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.springframework.metadata.Attributes;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import java.util.Collection;
+
 
 /**
  * Tests for {@link org.acegisecurity.annotation.SecurityAnnotationAttributes}
@@ -47,6 +49,67 @@ public class SecurityAnnotationAttributesTests extends TestCase {
         this.attributes = new SecurityAnnotationAttributes();
     }
 
+    public void testGenericsSuperclassDeclarationsAreIncludedWhenSubclassesOverride() {
+        Method method = null;
+
+        try {
+            method = DepartmentServiceImpl.class.getMethod("someUserMethod3", new Class[] {Department.class});
+        } catch (NoSuchMethodException unexpected) {
+            fail("Should be a superMethod called 'someUserMethod3' on class!");
+        }
+
+        Collection attrs = this.attributes.getAttributes(method);
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("attrs: ");
+            logger.debug(attrs);
+        }
+
+        assertNotNull(attrs);
+
+        // expect 1 attribute
+        assertTrue("Did not find 1 attribute", attrs.size() == 1);
+
+        // should have 1 SecurityConfig
+        for (Object obj : attrs) {
+            assertTrue(obj instanceof SecurityConfig);
+
+            SecurityConfig sc = (SecurityConfig) obj;
+            assertEquals("Found an incorrect role", "ROLE_ADMIN", sc.getAttribute());
+        }
+
+        Method superMethod = null;
+
+        try {
+            superMethod = DepartmentServiceImpl.class.getMethod("someUserMethod3", new Class[] {Entity.class});
+        } catch (NoSuchMethodException unexpected) {
+            fail("Should be a superMethod called 'someUserMethod3' on class!");
+        }
+
+        System.out.println(superMethod);
+
+        Collection superAttrs = this.attributes.getAttributes(superMethod);
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("superAttrs: ");
+            logger.debug(superAttrs);
+        }
+
+        assertNotNull(superAttrs);
+
+        // TODO: Enable this part of the test once we can build against Spring 2.0+ and above only (SEC-274)
+        /*
+           // expect 1 attribute
+           assertTrue("Did not find 1 attribute", superAttrs.size() == 1);
+           // should have 1 SecurityConfig
+           for (Object obj : superAttrs) {
+               assertTrue(obj instanceof SecurityConfig);
+               SecurityConfig sc = (SecurityConfig) obj;
+               assertEquals("Found an incorrect role", "ROLE_ADMIN", sc.getAttribute());
+           }
+         */
+    }
+
     public void testGetAttributesClass() {
         Collection attrs = this.attributes.getAttributes(BusinessService.class);
 
@@ -134,59 +197,4 @@ public class SecurityAnnotationAttributesTests extends TestCase {
             fail("Unsupported method should have thrown an exception!");
         } catch (UnsupportedOperationException expected) {}
     }
-    
-    public void testGenericsSuperclassDeclarationsAreIncludedWhenSubclassesOverride() {
-
-        Method method = null;
-        try {
-            method = DepartmentServiceImpl.class.getMethod("someUserMethod3", new Class[]{Department.class});
-        } catch (NoSuchMethodException unexpected) {
-            fail("Should be a superMethod called 'someUserMethod3' on class!");
-        }
-        Collection attrs = this.attributes.getAttributes(method);
-
-        if (logger.isDebugEnabled()) {
-            logger.debug("attrs: ");
-            logger.debug(attrs);
-        }
-        assertNotNull(attrs);
-
-        // expect 1 attribute
-        assertTrue("Did not find 1 attribute", attrs.size() == 1);
-
-        // should have 1 SecurityConfig
-        for (Object obj : attrs) {
-            assertTrue(obj instanceof SecurityConfig);
-            SecurityConfig sc = (SecurityConfig) obj;
-            assertEquals("Found an incorrect role", "ROLE_ADMIN", sc.getAttribute());
-        }
-
-        Method superMethod = null;
-        try {
-            superMethod = DepartmentServiceImpl.class.getMethod("someUserMethod3", new Class[]{Entity.class});
-        } catch (NoSuchMethodException unexpected) {
-            fail("Should be a superMethod called 'someUserMethod3' on class!");
-        }
-        System.out.println(superMethod);
-        Collection superAttrs = this.attributes.getAttributes(superMethod);
-
-        if (logger.isDebugEnabled()) {
-            logger.debug("superAttrs: ");
-            logger.debug(superAttrs);
-        }
-        assertNotNull(superAttrs);
-        
-        // TODO: Resolve bridge method bug as reported in SEC-274
-        /*
-        // expect 1 attribute
-        assertTrue("Did not find 1 attribute", superAttrs.size() == 1);
-
-        // should have 1 SecurityConfig
-        for (Object obj : superAttrs) {
-            assertTrue(obj instanceof SecurityConfig);
-            SecurityConfig sc = (SecurityConfig) obj;
-            assertEquals("Found an incorrect role", "ROLE_ADMIN", sc.getAttribute());
-        }
-        */
-    }   
 }