Преглед на файлове

SEC-1236: Using HTTP Method-specific intercept-urls causes patterns with no method to be ignored. Fixed by also checking null key in map if no method-specific attributes are found.

Luke Taylor преди 16 години
родител
ревизия
f518da9d8b

+ 21 - 14
web/src/main/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSource.java

@@ -180,28 +180,35 @@ public class DefaultFilterInvocationSecurityMetadataSource implements FilterInvo
         }
 
         // Obtain the map of request patterns to attributes for this method and lookup the url.
-        Map<Object, List<ConfigAttribute>> requestMap = httpMethodMap.get(method);
+        List<ConfigAttribute> attributes = extractMatchingAttributes(url, httpMethodMap.get(method));
 
-        // If no method-specific map, use the general one stored under the null key
+        // If no attributes found in method-specific map, use the general one stored under the null key
+        if (attributes == null) {
+            attributes = extractMatchingAttributes(url, httpMethodMap.get(null));
+        }
+
+        return attributes;
+    }
+
+    private List<ConfigAttribute> extractMatchingAttributes(String url, Map<Object, List<ConfigAttribute>> requestMap) {
         if (requestMap == null) {
-            requestMap = httpMethodMap.get(null);
+            return null;
         }
 
-        if (requestMap != null) {
-            for (Map.Entry<Object, List<ConfigAttribute>> entry : requestMap.entrySet()) {
-                Object p = entry.getKey();
-                boolean matched = urlMatcher.pathMatchesUrl(entry.getKey(), url);
+        final boolean debug = logger.isDebugEnabled();
 
-                if (logger.isDebugEnabled()) {
-                    logger.debug("Candidate is: '" + url + "'; pattern is " + p + "; matched=" + matched);
-                }
+        for (Map.Entry<Object, List<ConfigAttribute>> entry : requestMap.entrySet()) {
+            Object p = entry.getKey();
+            boolean matched = urlMatcher.pathMatchesUrl(entry.getKey(), url);
 
-                if (matched) {
-                    return entry.getValue();
-                }
+            if (debug) {
+                logger.debug("Candidate is: '" + url + "'; pattern is " + p + "; matched=" + matched);
             }
-        }
 
+            if (matched) {
+                return entry.getValue();
+            }
+        }
         return null;
     }
 

+ 15 - 0
web/src/test/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSourceTests.java

@@ -165,6 +165,21 @@ public class DefaultFilterInvocationSecurityMetadataSourceTests {
         assertEquals(postOnlyDef, attrs);
     }
 
+    // SEC-1236
+    @Test
+    public void mixingPatternsWithAndWithoutHttpMethodsIsSupported() throws Exception {
+        LinkedHashMap requestMap = new LinkedHashMap();
+        List<ConfigAttribute> userAttrs = SecurityConfig.createList("A");
+        requestMap.put(new RequestKey("/user/**", null), userAttrs);
+        requestMap.put(new RequestKey("/teller/**", "GET"), SecurityConfig.createList("B"));
+        fids = new DefaultFilterInvocationSecurityMetadataSource(new AntUrlPathMatcher(), requestMap);
+        fids.setStripQueryStringFromUrls(true);
+
+        FilterInvocation fi = createFilterInvocation("/user", "GET");
+        List<ConfigAttribute> attrs = fids.getAttributes(fi);
+        assertEquals(userAttrs, attrs);
+    }
+
     /**
      * Check fixes for SEC-321
      */