Przeglądaj źródła

SEC-1309: Namespace configurations should support Spring EL. Removed premature conversion of URL paths to lower case, which messes up if they are case-sensitive expressions or placeholders. Some other minor changes to suppport EL configuration.

Luke Taylor 15 lat temu
rodzic
commit
eddde8ea28

+ 3 - 11
config/src/main/java/org/springframework/security/config/http/FilterInvocationSecurityMetadataSourceParser.java

@@ -65,11 +65,10 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
 
     static BeanDefinition createSecurityMetadataSource(List<Element> interceptUrls, Element elt, ParserContext pc) {
         UrlMatcher matcher = HttpSecurityBeanDefinitionParser.createUrlMatcher(elt);
-        boolean convertPathsToLowerCase = (matcher instanceof AntUrlPathMatcher) && matcher.requiresLowerCaseUrl();
         boolean useExpressions = isUseExpressions(elt);
 
         ManagedMap<BeanDefinition, BeanDefinition> requestToAttributesMap = parseInterceptUrlsForFilterInvocationRequestMap(
-                interceptUrls, convertPathsToLowerCase, useExpressions, pc);
+                interceptUrls, useExpressions, pc);
         BeanDefinitionBuilder fidsBuilder;
 
         if (useExpressions) {
@@ -105,7 +104,7 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
     }
 
     private static ManagedMap<BeanDefinition, BeanDefinition> parseInterceptUrlsForFilterInvocationRequestMap(List<Element> urlElts,
-            boolean useLowerCasePaths, boolean useExpressions, ParserContext parserContext) {
+            boolean useExpressions, ParserContext parserContext) {
 
         ManagedMap<BeanDefinition, BeanDefinition> filterInvocationDefinitionMap = new ManagedMap<BeanDefinition, BeanDefinition>();
 
@@ -121,17 +120,11 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
                 parserContext.getReaderContext().error("path attribute cannot be empty or null", urlElt);
             }
 
-            if (useLowerCasePaths) {
-                path = path.toLowerCase();
-            }
-
             String method = urlElt.getAttribute(ATT_HTTP_METHOD);
             if (!StringUtils.hasText(method)) {
                 method = null;
             }
 
-            // Use beans to
-
             BeanDefinitionBuilder keyBldr = BeanDefinitionBuilder.rootBeanDefinition(RequestKey.class);
             keyBldr.addConstructorArgValue(path);
             keyBldr.addConstructorArgValue(method);
@@ -141,7 +134,7 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
 
             if (useExpressions) {
                 logger.info("Creating access control expression attribute '" + access + "' for " + path);
-                // The expression will be parsed later by the ExpressionFilterInvocationSecurityMetadataSource
+                // The single expression will be parsed later by the ExpressionFilterInvocationSecurityMetadataSource
                 attributeBuilder.setFactoryMethod("createList");
 
             } else {
@@ -160,5 +153,4 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
         return filterInvocationDefinitionMap;
     }
 
-
 }

+ 9 - 10
config/src/main/java/org/springframework/security/config/http/PortMappingsBeanDefinitionParser.java

@@ -1,20 +1,19 @@
 package org.springframework.security.config.http;
 
-import org.springframework.security.config.Elements;
-import org.springframework.security.web.PortMapperImpl;
-import org.springframework.beans.factory.xml.BeanDefinitionParser;
-import org.springframework.beans.factory.xml.ParserContext;
+import java.util.List;
+import java.util.Map;
+
 import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.ManagedMap;
 import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.security.config.Elements;
+import org.springframework.security.web.PortMapperImpl;
 import org.springframework.util.StringUtils;
 import org.springframework.util.xml.DomUtils;
-
 import org.w3c.dom.Element;
 
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
-
 /**
  * Parses a port-mappings element, producing a single {@link org.springframework.security.web.PortMapperImpl}
  * bean.
@@ -37,7 +36,7 @@ class PortMappingsBeanDefinitionParser implements BeanDefinitionParser {
                 parserContext.getReaderContext().error("No port-mapping child elements specified", element);
             }
 
-            Map mappings = new HashMap();
+            Map mappings = new ManagedMap();
 
             for (Element elt : mappingElts) {
                 String httpPort = elt.getAttribute(ATT_HTTP_PORT);

+ 31 - 10
config/src/test/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParserTests.java

@@ -329,7 +329,7 @@ public class HttpSecurityBeanDefinitionParserTests {
     // SEC-1201
     @Test
     public void interceptUrlsAndFormLoginSupportPropertyPlaceholders() throws Exception {
-        System.setProperty("secure.url", "/secure");
+        System.setProperty("secure.Url", "/Secure");
         System.setProperty("secure.role", "ROLE_A");
         System.setProperty("login.page", "/loginPage");
         System.setProperty("default.target", "/defaultTarget");
@@ -337,11 +337,32 @@ public class HttpSecurityBeanDefinitionParserTests {
         setContext(
                 "<b:bean class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'/>" +
                 "<http>" +
-                "    <intercept-url pattern='${secure.url}' access='${secure.role}' />" +
+                "    <intercept-url pattern='${secure.Url}' access='${secure.role}' />" +
                 "    <form-login login-page='${login.page}' default-target-url='${default.target}' " +
                 "        authentication-failure-url='${auth.failure}' />" +
                 "</http>" + AUTH_PROVIDER_XML);
+        checkPropertyValues() ;
+    }
+
+    // SEC-1309
+    @Test
+    public void interceptUrlsAndFormLoginSupportEL() throws Exception {
+        System.setProperty("secure.url", "/Secure");
+        System.setProperty("secure.role", "ROLE_A");
+        System.setProperty("login.page", "/loginPage");
+        System.setProperty("default.target", "/defaultTarget");
+        System.setProperty("auth.failure", "/authFailure");
+        setContext(
+                "<b:bean class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'/>" +
+                "<http>" +
+                "    <intercept-url pattern=\"#{systemProperties['secure.url']}\" access=\"#{systemProperties['secure.role']}\" />" +
+                "    <form-login login-page=\"#{systemProperties['login.page']}\" default-target-url=\"#{systemProperties['default.target']}\" " +
+                "        authentication-failure-url=\"#{systemProperties['auth.failure']}\" />" +
+                "</http>" + AUTH_PROVIDER_XML);
+        checkPropertyValues() ;
+    }
 
+    private void checkPropertyValues() throws Exception {
         // Check the security attribute
         FilterSecurityInterceptor fis = (FilterSecurityInterceptor) getFilter(FilterSecurityInterceptor.class);
         FilterInvocationSecurityMetadataSource fids = fis.getSecurityMetadataSource();
@@ -452,14 +473,14 @@ public class HttpSecurityBeanDefinitionParserTests {
     }
 
     @Test
-    public void portMappingsWorkWithPlaceholders() throws Exception {
+    public void portMappingsWorkWithPlaceholdersAndEL() throws Exception {
         System.setProperty("http", "9080");
         System.setProperty("https", "9443");
         setContext(
                 "    <b:bean id='configurer' class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'/>" +
                 "    <http auto-config='true'>" +
                 "        <port-mappings>" +
-                "            <port-mapping http='${http}' https='${https}'/>" +
+                "            <port-mapping http='#{systemProperties.http}' https='${https}'/>" +
                 "        </port-mappings>" +
                 "    </http>" + AUTH_PROVIDER_XML);
 
@@ -475,7 +496,7 @@ public class HttpSecurityBeanDefinitionParserTests {
     }
 
     @Test
-    public void accessDeniedPageWorkWithPlaceholders() throws Exception {
+    public void accessDeniedPageWorksWithPlaceholders() throws Exception {
         System.setProperty("accessDenied", "/go-away");
         setContext(
                 "    <b:bean id='configurer' class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'/>" +
@@ -485,10 +506,10 @@ public class HttpSecurityBeanDefinitionParserTests {
     }
 
     @Test
-    public void accessDeniedHandlerPageIsSetCorectly() throws Exception {
+    public void accessDeniedHandlerPageWorksWithEL() throws Exception {
         setContext(
                 "    <http auto-config='true'>" +
-                "        <access-denied-handler error-page='/go-away'/>" +
+                "        <access-denied-handler error-page=\"#{'/go' + '-away'} \" />" +
                 "    </http>" + AUTH_PROVIDER_XML);
         ExceptionTranslationFilter filter = (ExceptionTranslationFilter) getFilter(ExceptionTranslationFilter.class);
         assertEquals("/go-away", FieldUtils.getFieldValue(filter, "accessDeniedHandler.errorPage"));
@@ -507,7 +528,7 @@ public class HttpSecurityBeanDefinitionParserTests {
     }
 
     @Test(expected=BeanDefinitionParsingException.class)
-    public void accessDeniedHandlerAndAccessDeniedHandlerAreMutuallyExclusive() throws Exception {
+    public void accessDeniedPageAndAccessDeniedHandlerAreMutuallyExclusive() throws Exception {
         setContext(
                 "    <http auto-config='true' access-denied-page='/go-away'>" +
                 "        <access-denied-handler error-page='/go-away'/>" +
@@ -595,11 +616,11 @@ public class HttpSecurityBeanDefinitionParserTests {
     public void rememberMeServiceWorksWithExternalServicesImpl() throws Exception {
         setContext(
                 "<http auto-config='true'>" +
-                "    <remember-me key='ourkey' services-ref='rms'/>" +
+                "    <remember-me key=\"#{'our' + 'key'}\" services-ref='rms'/>" +
                 "</http>" +
                 "<b:bean id='rms' class='"+ TokenBasedRememberMeServices.class.getName() +"'> " +
                 "    <b:property name='userDetailsService' ref='us'/>" +
-                "    <b:property name='key' value='ourkey'/>" +
+                "    <b:property name='key' value='ourkey' />" +
                 "    <b:property name='tokenValiditySeconds' value='5000'/>" +
                 "</b:bean>" +
                 AUTH_PROVIDER_XML);