Procházet zdrojové kódy

SEC-1201: PropertyPlaceholderConfigurer does not work for intercept-url attributes. Ensure that channel processing handles paths which are placeholders.

Luke Taylor před 16 roky
rodič
revize
ea01e9cdf7

+ 13 - 12
config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java

@@ -6,7 +6,6 @@ import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -181,7 +180,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
         // Use ManagedMap to allow placeholder resolution
         final ManagedMap<String, List<BeanMetadataElement>> filterChainMap =
             parseInterceptUrlsForEmptyFilterChains(interceptUrls, convertPathsToLowerCase, pc);
-        final LinkedHashMap<RequestKey, List<ConfigAttribute>> channelRequestMap =
+        final ManagedMap<BeanDefinition,List<ConfigAttribute>> channelRequestMap =
                 parseInterceptUrlsForChannelSecurity(interceptUrls, convertPathsToLowerCase, pc);
 
         BeanDefinition cpf = null;
@@ -894,14 +893,14 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
     }
 
     private BeanDefinition createChannelProcessingFilter(ParserContext pc, UrlMatcher matcher,
-            LinkedHashMap<RequestKey, List<ConfigAttribute>> channelRequestMap, String portMapperBeanName) {
+            ManagedMap<BeanDefinition,List<ConfigAttribute>> channelRequestMap, String portMapperBeanName) {
         RootBeanDefinition channelFilter = new RootBeanDefinition(ChannelProcessingFilter.class);
+        BeanDefinitionBuilder metadataSourceBldr = BeanDefinitionBuilder.rootBeanDefinition(DefaultFilterInvocationSecurityMetadataSource.class);
+        metadataSourceBldr.addConstructorArgValue(matcher);
+        metadataSourceBldr.addConstructorArgValue(channelRequestMap);
+        metadataSourceBldr.addPropertyValue("stripQueryStringFromUrls", matcher instanceof AntUrlPathMatcher);
 
-        DefaultFilterInvocationSecurityMetadataSource channelFilterInvDefSource =
-            new DefaultFilterInvocationSecurityMetadataSource(matcher, channelRequestMap);
-        channelFilterInvDefSource.setStripQueryStringFromUrls(matcher instanceof AntUrlPathMatcher);
-
-        channelFilter.getPropertyValues().addPropertyValue("securityMetadataSource", channelFilterInvDefSource);
+        channelFilter.getPropertyValues().addPropertyValue("securityMetadataSource", metadataSourceBldr.getBeanDefinition());
         RootBeanDefinition channelDecisionManager = new RootBeanDefinition(ChannelDecisionManagerImpl.class);
         ManagedList<RootBeanDefinition> channelProcessors = new ManagedList<RootBeanDefinition>(3);
         RootBeanDefinition secureChannelProcessor = new RootBeanDefinition(SecureChannelProcessor.class);
@@ -1196,10 +1195,10 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
      * map used to create the FilterInvocationDefintionSource for the FilterSecurityInterceptor.
      * @return
      */
-    LinkedHashMap<RequestKey, List<ConfigAttribute>> parseInterceptUrlsForChannelSecurity(List<Element> urlElts,
+    private ManagedMap<BeanDefinition,List<ConfigAttribute>> parseInterceptUrlsForChannelSecurity(List<Element> urlElts,
             boolean useLowerCasePaths, ParserContext parserContext) {
 
-        LinkedHashMap<RequestKey, List<ConfigAttribute>> channelRequestMap = new ManagedMap<RequestKey, List<ConfigAttribute>>();
+        ManagedMap<BeanDefinition, List<ConfigAttribute>> channelRequestMap = new ManagedMap<BeanDefinition, List<ConfigAttribute>>();
 
         for (Element urlElt : urlElts) {
             String path = urlElt.getAttribute(ATT_PATH_PATTERN);
@@ -1227,8 +1226,10 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
                     parserContext.getReaderContext().error("Unsupported channel " + requiredChannel, urlElt);
                 }
 
-                channelRequestMap.put(new RequestKey(path),
-                        SecurityConfig.createList((StringUtils.commaDelimitedListToStringArray(channelConfigAttribute))));
+                BeanDefinition requestKey = new RootBeanDefinition(RequestKey.class);
+                requestKey.getConstructorArgumentValues().addGenericArgumentValue(path);
+
+                channelRequestMap.put(requestKey, SecurityConfig.createList(channelConfigAttribute));
             }
         }
 

+ 4 - 2
config/src/test/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParserTests.java

@@ -390,11 +390,13 @@ public class HttpSecurityBeanDefinitionParserTests {
 
     @Test
     public void requiresChannelSupportsPlaceholder() throws Exception {
+        System.setProperty("secure.url", "/secure");
         setContext(
+                "    <b:bean id='configurer' class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'/>" +                
                 "    <http auto-config='true'>" +
-                "        <intercept-url pattern='/**' requires-channel='https' />" +
+                "        <intercept-url pattern='${secure.url}' requires-channel='https' />" +
                 "    </http>" + AUTH_PROVIDER_XML);
-        List<Filter> filters = getFilters("/someurl");
+        List<Filter> filters = getFilters("/secure");
 
         assertEquals("Expected " + (AUTO_CONFIG_FILTERS + 1) +"  filters in chain", AUTO_CONFIG_FILTERS + 1, filters.size());