diff --git a/config/src/main/java/org/springframework/security/config/BeanIds.java b/config/src/main/java/org/springframework/security/config/BeanIds.java index 2af6d915f4..c443618b5b 100644 --- a/config/src/main/java/org/springframework/security/config/BeanIds.java +++ b/config/src/main/java/org/springframework/security/config/BeanIds.java @@ -9,7 +9,7 @@ package org.springframework.security.config; * @version $Id: BeanIds.java 3770 2009-07-15 23:09:47Z ltaylor $ */ public abstract class BeanIds { - private static final String PREFIX = "org.springframework.security"; + private static final String PREFIX = "org.springframework.security."; /** The "global" AuthenticationManager instance, registered by the element */ public static final String AUTHENTICATION_MANAGER = PREFIX + "authenticationManager"; 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 index 1ce25f37ef..7f3eb0561c 100644 --- a/config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerFactoryBean.java +++ b/config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerFactoryBean.java @@ -1,7 +1,5 @@ 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; @@ -21,17 +19,18 @@ import org.springframework.security.config.BeanIds; * @since 3.0 */ public class AuthenticationManagerFactoryBean implements FactoryBean, BeanFactoryAware { - private final Log logger = LogFactory.getLog(getClass()); private BeanFactory bf; + public static final String MISSING_BEAN_ERROR_MESSAGE = "Did you forget to add an element " + + "to your configuration (with child elements) ?"; 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 ?"); + if (BeanIds.AUTHENTICATION_MANAGER.equals(e.getBeanName())) { + throw new NoSuchBeanDefinitionException(BeanIds.AUTHENTICATION_MANAGER, MISSING_BEAN_ERROR_MESSAGE); + } + throw e; } } diff --git a/config/src/main/java/org/springframework/security/config/method/GlobalMethodSecurityBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/method/GlobalMethodSecurityBeanDefinitionParser.java index 3b954b8037..4024e2f553 100644 --- a/config/src/main/java/org/springframework/security/config/method/GlobalMethodSecurityBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/method/GlobalMethodSecurityBeanDefinitionParser.java @@ -14,6 +14,7 @@ import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanReference; import org.springframework.beans.factory.config.RuntimeBeanReference; @@ -48,6 +49,7 @@ import org.springframework.security.authentication.AuthenticationManager; 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.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.util.Assert; @@ -77,7 +79,6 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP private static final String ATT_REF = "ref"; private static final String ATT_ADVICE_ORDER = "order"; - // @SuppressWarnings("unchecked") public BeanDefinition parse(Element element, ParserContext pc) { CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), pc.extractSource(element)); @@ -287,7 +288,6 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP String runAsManagerId, BeanReference metadataSource, List afterInvocationProviders, Object source) { BeanDefinitionBuilder bldr = BeanDefinitionBuilder.rootBeanDefinition(MethodSecurityInterceptor.class); bldr.getRawBeanDefinition().setSource(source); - bldr.addPropertyReference("accessDecisionManager", accessManagerId); bldr.addPropertyValue("authenticationManager", new RootBeanDefinition(AuthenticationManagerDelegator.class)); bldr.addPropertyValue("securityMetadataSource", metadataSource); @@ -335,7 +335,7 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP * @author Luke Taylor * @since 3.0 */ - public static final class AuthenticationManagerDelegator implements AuthenticationManager, BeanFactoryAware { + static final class AuthenticationManagerDelegator implements AuthenticationManager, BeanFactoryAware { private AuthenticationManager delegate; private final Object delegateMonitor = new Object(); private BeanFactory beanFactory; @@ -344,7 +344,15 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP synchronized(delegateMonitor) { if (delegate == null) { Assert.state(beanFactory != null, "BeanFactory must be set to resolve " + BeanIds.AUTHENTICATION_MANAGER); - delegate = beanFactory.getBean(BeanIds.AUTHENTICATION_MANAGER, ProviderManager.class); + try { + delegate = beanFactory.getBean(BeanIds.AUTHENTICATION_MANAGER, ProviderManager.class); + } catch (NoSuchBeanDefinitionException e) { + if (BeanIds.AUTHENTICATION_MANAGER.equals(e.getBeanName())) { + throw new NoSuchBeanDefinitionException(BeanIds.AUTHENTICATION_MANAGER, + AuthenticationManagerFactoryBean.MISSING_BEAN_ERROR_MESSAGE); + } + throw e; + } } } diff --git a/config/src/test/java/org/springframework/security/config/InvalidConfigurationTests.java b/config/src/test/java/org/springframework/security/config/InvalidConfigurationTests.java index 2c8144d318..49c421b832 100644 --- a/config/src/test/java/org/springframework/security/config/InvalidConfigurationTests.java +++ b/config/src/test/java/org/springframework/security/config/InvalidConfigurationTests.java @@ -1,34 +1,56 @@ package org.springframework.security.config; +import static org.junit.Assert.*; + import org.junit.After; import org.junit.Test; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException; +import org.springframework.security.config.authentication.AuthenticationManagerFactoryBean; import org.springframework.security.config.util.InMemoryXmlApplicationContext; /** - * Tests which make sure invalid configurations are rejected by the namespace. In particular invalid top-level + * Tests which make sure invalid configurations are rejected by the namespace. In particular invalid top-level * elements. These are likely to fail after the namespace has been updated using trang, but the spring-security.xsl - * transform has not been applied. - * + * transform has not been applied. + * * @author Luke Taylor * @version $Id$ */ public class InvalidConfigurationTests { private InMemoryXmlApplicationContext appContext; - + @After public void closeAppContext() { if (appContext != null) { appContext.close(); } - } - + } + // Parser should throw a SAXParseException @Test(expected=XmlBeanDefinitionStoreException.class) public void passwordEncoderCannotAppearAtTopLevel() { setContext(""); } - + + @Test(expected=XmlBeanDefinitionStoreException.class) + public void authenticationProviderCannotAppearAtTopLevel() { + setContext(""); + } + + @Test + public void missingAuthenticationManagerGivesSensibleErrorMessage() { + try { + setContext(""); + } catch (BeanCreationException e) { + assertTrue(e.getCause().getCause() instanceof NoSuchBeanDefinitionException); + NoSuchBeanDefinitionException nsbe = (NoSuchBeanDefinitionException) e.getCause().getCause(); + assertEquals(BeanIds.AUTHENTICATION_MANAGER, nsbe.getBeanName()); + assertTrue(nsbe.getMessage().endsWith(AuthenticationManagerFactoryBean.MISSING_BEAN_ERROR_MESSAGE)); + } + } + private void setContext(String context) { appContext = new InMemoryXmlApplicationContext(context); }