瀏覽代碼

OPEN - issue SEC-742: IllegalArgumentException if namespace configuration defines RememberMeServices without BasicProcessingFilter
http://jira.springframework.org/browse/SEC-742. Fix. Post processor was assuming there was a BasicProcessinFilter in the app context when a remember-me services was present.

Luke Taylor 17 年之前
父節點
當前提交
f898bec370

+ 10 - 17
core/src/main/java/org/springframework/security/config/HttpSecurityConfigPostProcessor.java

@@ -130,8 +130,8 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
     }
 
     /**
-     * Sets the authentication manager, (and remember-me services, if required) on any instances of
-     * AbstractProcessingFilter
+     * Sets the remember-me services, if required, on any instances of AbstractProcessingFilter and 
+     * BasicProcessingFilter.
      */
     private void injectRememberMeServicesIntoFiltersRequiringIt(ConfigurableListableBeanFactory beanFactory) {
         Map beans = beanFactory.getBeansOfType(RememberMeServices.class);
@@ -148,6 +148,10 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
         } else {
             throw new SecurityConfigurationException("More than one RememberMeServices bean found.");
         }
+        
+        if (rememberMeServices == null) {
+            return;
+        }
 
         // Address AbstractProcessingFilter instances
         Iterator filters = beanFactory.getBeansOfType(AbstractProcessingFilter.class).values().iterator();
@@ -155,10 +159,8 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
         while (filters.hasNext()) {
             AbstractProcessingFilter filter = (AbstractProcessingFilter) filters.next();
 
-            if (rememberMeServices != null) {
-                logger.info("Using RememberMeServices " + rememberMeServices + " with filter " + filter);
-                filter.setRememberMeServices(rememberMeServices);
-            }
+            logger.info("Using RememberMeServices " + rememberMeServices + " with filter " + filter);
+            filter.setRememberMeServices(rememberMeServices);
         }
 
         // Address BasicProcessingFilter instance, if it exists
@@ -166,13 +168,12 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
         // Most of the time a user won't present such a parameter with their BASIC authentication request.
         // In the future we might support setting the AbstractRememberMeServices.alwaysRemember = true, but I am reluctant to
         // do so because it seems likely to lead to lower security for 99.99% of users if they set the property to true.
-       	BasicProcessingFilter filter = (BasicProcessingFilter) getBeanOfType(BasicProcessingFilter.class, beanFactory);
+        if (beanFactory.containsBean(BeanIds.BASIC_AUTHENTICATION_FILTER)) {
+            BasicProcessingFilter filter = (BasicProcessingFilter) beanFactory.getBean(BeanIds.BASIC_AUTHENTICATION_FILTER);
 
-        if (filter != null && rememberMeServices != null) {
             logger.info("Using RememberMeServices " + rememberMeServices + " with filter " + filter);
             filter.setRememberMeServices(rememberMeServices);
         }
-
     }
 
     /**
@@ -281,14 +282,6 @@ public class HttpSecurityConfigPostProcessor implements BeanFactoryPostProcessor
         return orderedFilters;
     }
 
-    private Object getBeanOfType(Class clazz, ConfigurableListableBeanFactory beanFactory) {
-        Map beans = beanFactory.getBeansOfType(clazz);
-
-        Assert.isTrue(beans.size() == 1, "Required a single bean of type " + clazz + " but found " + beans.size());
-
-        return beans.values().toArray()[0];
-    }
-
     public int getOrder() {
         return HIGHEST_PRECEDENCE + 1;
     }

+ 12 - 0
core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java

@@ -325,6 +325,18 @@ public class HttpSecurityBeanDefinitionParserTests {
         assertTrue("ExceptionTranslationFilter should be configured with custom entry point", 
                 etf.getAuthenticationEntryPoint() instanceof MockAuthenticationEntryPoint);
     }
+    
+    @Test
+    /** SEC-742 */
+    public void rememberMeServicesWorksWithoutBasicProcessingFilter() {
+        setContext(
+                "    <http>" +
+                "        <form-login login-page='/login.jsp' default-target-url='/messageList.html'/>" +
+                "        <logout logout-success-url='/login.jsp'/>" +
+                "        <anonymous username='guest' granted-authority='guest'/>" +
+                "        <remember-me />" +
+                "    </http>" + AUTH_PROVIDER_XML);
+    }
 
     @Test
     public void disablingSessionProtectionRemovesFilter() throws Exception {