浏览代码

SEC-1826: Empty attribute list should be treated the same as null in DelegatingMethodSecurityMetadataSource.

Luke Taylor 14 年之前
父节点
当前提交
44364d0101

+ 2 - 2
core/src/main/java/org/springframework/security/access/SecurityMetadataSource.java

@@ -35,8 +35,8 @@ public interface SecurityMetadataSource extends AopInfrastructureBean {
      *
      * @param object the object being secured
      *
-     * @return the attributes that apply to the passed in secured object. Can return either {@code null} or an
-     *         empty collection if there are no applicable attributes.
+     * @return the attributes that apply to the passed in secured object. Should return an empty collection if there
+     *         are no applicable attributes.
      *
      * @throws IllegalArgumentException if the passed object is not of a type supported by the
      *         <code>SecurityMetadataSource</code> implementation

+ 4 - 7
core/src/main/java/org/springframework/security/access/method/DelegatingMethodSecurityMetadataSource.java

@@ -15,7 +15,7 @@ import org.springframework.util.ObjectUtils;
 
 /**
  * Automatically tries a series of method definition sources, relying on the first source of metadata
- * that provides a non-null response. Provides automatic caching of the retrieved metadata.
+ * that provides a non-null/non-empty response. Provides automatic caching of the retrieved metadata.
  *
  * @author Ben Alex
  * @author Luke Taylor
@@ -41,9 +41,6 @@ public final class DelegatingMethodSecurityMetadataSource extends AbstractMethod
         synchronized (attributeCache) {
             Collection<ConfigAttribute> cached = attributeCache.get(cacheKey);
             // Check for canonical value indicating there is no config attribute,
-            if (cached == NULL_CONFIG_ATTRIBUTE) {
-                return null;
-            }
 
             if (cached != null) {
                 return cached;
@@ -59,13 +56,13 @@ public final class DelegatingMethodSecurityMetadataSource extends AbstractMethod
             }
 
             // Put it in the cache.
-            if (attributes == null) {
+            if (attributes == null || attributes.isEmpty()) {
                 this.attributeCache.put(cacheKey, NULL_CONFIG_ATTRIBUTE);
-                return null;
+                return NULL_CONFIG_ATTRIBUTE;
             }
 
             if (logger.isDebugEnabled()) {
-                logger.debug("Adding security method [" + cacheKey + "] with attributes " + attributes);
+                logger.debug("Caching method [" + cacheKey + "] with attributes " + attributes);
             }
 
             this.attributeCache.put(cacheKey, attributes);

+ 3 - 3
core/src/test/java/org/springframework/security/access/method/DelegatingMethodSecurityMetadataSourceTests.java

@@ -20,7 +20,7 @@ public class DelegatingMethodSecurityMetadataSourceTests {
     DelegatingMethodSecurityMetadataSource mds;
 
     @Test
-    public void returnsNullIfDelegateReturnsNull() throws Exception {
+    public void returnsEmptyListIfDelegateReturnsNull() throws Exception {
         List sources = new ArrayList();
         MethodSecurityMetadataSource delegate = mock(MethodSecurityMetadataSource.class);
         when(delegate.getAttributes(Matchers.<Method>any(), Matchers.any(Class.class))).thenReturn(null);
@@ -29,9 +29,9 @@ public class DelegatingMethodSecurityMetadataSourceTests {
         assertSame(sources, mds.getMethodSecurityMetadataSources());
         assertTrue(mds.getAllConfigAttributes().isEmpty());
         MethodInvocation mi = new SimpleMethodInvocation(null, String.class.getMethod("toString"));
-        assertNull(mds.getAttributes(mi));
+        assertEquals(Collections.emptyList(), mds.getAttributes(mi));
         // Exercise the cached case
-        assertNull(mds.getAttributes(mi));
+        assertEquals(Collections.emptyList(), mds.getAttributes(mi));
     }
 
     @Test