Describe the bug When defining two AuthenticationManager using XML beans definition and having AllowBeanDefinitionOverriding set to false the bean parser fails with the following exception:
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [spring-security-config.xml]; nested exception is java.lang.IllegalStateException: Cannot define alias 'org.springframework.security.authenticationManager' for name 'manager2': It is already registered for name 'manager1'.
To Reproduce Create XML beans definition containing two AuthenticationManager beans
spring-security-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<authentication-manager id="manager1">
</authentication-manager>
<authentication-manager id="manager2">
</authentication-manager>
</beans:beans>
SecurityBeansTest.java
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
@Configuration
@ImportResource({ "classpath:/spring-security-config.xml" })
public class SecurityBeansTest {
}
Configure org.springframework.context.support.AbstractRefreshableApplicationContext#setAllowBeanDefinitionOverriding to false and create test that instantiates the beans
import org.junit.jupiter.api.Test;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
public class ContextTest {
@Test
void test() {
final AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(SecurityBeansTest.class);
rootContext.setAllowBeanDefinitionOverriding(false);
rootContext.refresh();
}
}
Expected behaviour Beans context can be created successfully.
Actual behaviour This exception is thrown
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [spring-security-config.xml]; nested exception is java.lang.IllegalStateException: Cannot define alias 'org.springframework.security.authenticationManager' for name 'manager2': It is already registered for name 'manager1'.
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:417)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:338)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:224)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:195)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.lambda$loadBeanDefinitionsFromImportedResources$0
What I found out so far is that the method org.springframework.security.config.authentication.AuthenticationManagerBeanDefinitionParser#parse tries to create aliases with the same name for every AuthenticationManager bean in this code
if (!BeanIds.AUTHENTICATION_MANAGER.equals(id)) {
pc.getRegistry().registerAlias(id, BeanIds.AUTHENTICATION_MANAGER);
which causes that the two beans get the same alias which fails.
I am using Spring security version 4.2.17.RELEASE. This happend after upgrading from version 3.1.0.RELEASE where it used to work.
Comment From: jojocodeX
The bean is used as a manager and there is often no need to define two managers
Comment From: rwinch
@felixkl Can you describe why you need multiple authentication managers? At that point I wonder which manager would be wired into Spring Security?
Comment From: felixkl
We have an authorization service which handles two authorize use cases on different urls. For each of these we have a separate AuthenticationManager defined so we have a separation of the used AuthenticationProviders. So actually both managers are used, each for a specified path.