diff --git a/config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerFactoryBean.java b/config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerFactoryBean.java
new file mode 100644
index 0000000000..1ce25f37ef
--- /dev/null
+++ b/config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerFactoryBean.java
@@ -0,0 +1,50 @@
+package org.springframework.security.config.authentication;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.config.BeanIds;
+
+/**
+ * Factory bean for the namespace AuthenticationManager, which allows a more meaningful error message
+ * to be reported in the NoSuchBeanDefinitionException, if the user has forgotten to declare
+ * the <authentication-manager> element.
+ *
+ * @author Luke Taylor
+ * @version $Id$
+ * @since 3.0
+ */
+public class AuthenticationManagerFactoryBean implements FactoryBean, BeanFactoryAware {
+ private final Log logger = LogFactory.getLog(getClass());
+ private BeanFactory bf;
+
+ public AuthenticationManager getObject() throws Exception {
+ try {
+ return (AuthenticationManager) bf.getBean(BeanIds.AUTHENTICATION_MANAGER);
+ } catch (NoSuchBeanDefinitionException e) {
+ logger.error(BeanIds.AUTHENTICATION_MANAGER + " bean was not found in the application context.");
+ throw new NoSuchBeanDefinitionException("The namespace AuthenticationManager was not found. " +
+ "Did you forget to add an element to your configuration with " +
+ "child elements ?");
+ }
+ }
+
+ public Class extends AuthenticationManager> getObjectType() {
+ return ProviderManager.class;
+ }
+
+ public boolean isSingleton() {
+ return true;
+ }
+
+ public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
+ bf = beanFactory;
+ }
+
+}
diff --git a/config/src/main/java/org/springframework/security/config/authentication/NamespaceAuthenticationManager.java b/config/src/main/java/org/springframework/security/config/authentication/NamespaceAuthenticationManager.java
deleted file mode 100644
index 4428262bbc..0000000000
--- a/config/src/main/java/org/springframework/security/config/authentication/NamespaceAuthenticationManager.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.springframework.security.config.authentication;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.security.authentication.AuthenticationProvider;
-import org.springframework.security.authentication.ProviderManager;
-import org.springframework.util.Assert;
-
-/**
- * Extended version of {@link ProviderManager the default authentication manager} which lazily initializes
- * the list of {@link AuthenticationProvider}s. This prevents some of the issues that have occurred with
- * namespace configuration where early instantiation of a security interceptor has caused the AuthenticationManager
- * and thus dependent beans (typically UserDetailsService implementations or DAOs) to be initialized too early.
- *
- * @author Luke Taylor
- * @since 2.0.4
- */
-public class NamespaceAuthenticationManager extends ProviderManager implements BeanFactoryAware {
- private BeanFactory beanFactory;
- private List providerBeanNames;
-
- public void setBeanFactory(BeanFactory beanFactory) {
- this.beanFactory = beanFactory;
- }
-
- public void afterPropertiesSet() throws Exception {
- Assert.notNull(providerBeanNames, "provideBeanNames has not been set");
- Assert.notEmpty(providerBeanNames, "No authentication providers were found in the application context");
- }
-
- /**
- * Overridden to lazily-initialize the list of providers on first use.
- */
- public List getProviders() {
- // We use the names array to determine whether the list has been set yet.
- if (providerBeanNames != null) {
- ArrayList providers = new ArrayList();
- Iterator beanNames = providerBeanNames.iterator();
-
- while (beanNames.hasNext()) {
- providers.add((AuthenticationProvider) beanFactory.getBean(beanNames.next()));
- }
- providerBeanNames = null;
- providers.trimToSize();
-
- setProviders(providers);
- }
-
- return super.getProviders();
- }
-
- public void setProviderBeanNames(List provideBeanNames) {
- this.providerBeanNames = provideBeanNames;
- }
-}
diff --git a/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java
index 570f9e28d5..f6d7f7aa91 100644
--- a/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java
+++ b/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java
@@ -26,6 +26,7 @@ import org.springframework.core.Ordered;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.Elements;
+import org.springframework.security.config.authentication.AuthenticationManagerFactoryBean;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
import org.springframework.security.web.util.AntUrlPathMatcher;
@@ -171,7 +172,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
private BeanReference createAuthenticationManager(Element element, ParserContext pc,
ManagedList authenticationProviders, BeanReference concurrencyController) {
BeanDefinitionBuilder authManager = BeanDefinitionBuilder.rootBeanDefinition(ProviderManager.class);
- authManager.addPropertyReference("parent", BeanIds.AUTHENTICATION_MANAGER);
+ authManager.addPropertyValue("parent", new RootBeanDefinition(AuthenticationManagerFactoryBean.class));
authManager.addPropertyValue("providers", authenticationProviders);
if (concurrencyController != null) {