SEC:1263: Added FactoryBean for AuthenticationManager

This commit is contained in:
Luke Taylor 2009-10-09 12:11:45 +00:00
parent 217cffbdbc
commit ac5237c127
3 changed files with 52 additions and 60 deletions

View File

@ -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 <tt>NoSuchBeanDefinitionException</tt>, if the user has forgotten to declare
* the &lt;authentication-manager&gt; element.
*
* @author Luke Taylor
* @version $Id$
* @since 3.0
*/
public class AuthenticationManagerFactoryBean implements FactoryBean<AuthenticationManager>, 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 <authentication-manager> element to your configuration with " +
"child <authentication-provider> elements ?");
}
}
public Class<? extends AuthenticationManager> getObjectType() {
return ProviderManager.class;
}
public boolean isSingleton() {
return true;
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
bf = beanFactory;
}
}

View File

@ -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<String> 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<AuthenticationProvider> getProviders() {
// We use the names array to determine whether the list has been set yet.
if (providerBeanNames != null) {
ArrayList<AuthenticationProvider> providers = new ArrayList<AuthenticationProvider>();
Iterator<String> 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<String> provideBeanNames) {
this.providerBeanNames = provideBeanNames;
}
}

View File

@ -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<BeanReference> 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) {