ソースを参照

Multiple <authentication-manager> Do Not Duplicate Alias

Previously, two authentication managers with different ids would duplicate
the alias to the global authentication manager. This would cause failures
for when allowBeanDefinitionOverriding = false.

This commit ensures that if the global authentication manager alias is
already set, then it is not set again. This means the first
<authentication-manager> will be used as the global AuthenticationManager.

Closes gh-8767
Rob Winch 3 年 前
コミット
dec0d97ef0

+ 3 - 1
config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParser.java

@@ -102,7 +102,9 @@ public class AuthenticationManagerBeanDefinitionParser implements BeanDefinition
 			pc.getRegistry().registerAlias(id, alias);
 			pc.getReaderContext().fireAliasRegistered(id, alias, pc.extractSource(element));
 		}
-		if (!BeanIds.AUTHENTICATION_MANAGER.equals(id)) {
+		if (!BeanIds.AUTHENTICATION_MANAGER.equals(id)
+				&& !pc.getRegistry().containsBeanDefinition(BeanIds.AUTHENTICATION_MANAGER)
+				&& !pc.getRegistry().isAlias(BeanIds.AUTHENTICATION_MANAGER)) {
 			pc.getRegistry().registerAlias(id, BeanIds.AUTHENTICATION_MANAGER);
 			pc.getReaderContext().fireAliasRegistered(id, BeanIds.AUTHENTICATION_MANAGER, pc.extractSource(element));
 		}

+ 12 - 0
config/src/test/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParserTests.java

@@ -26,6 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationListener;
 import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.security.authentication.AuthenticationEventPublisher;
+import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.AuthenticationProvider;
 import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
 import org.springframework.security.authentication.ProviderManager;
@@ -33,6 +34,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
 import org.springframework.security.authentication.event.AbstractAuthenticationEvent;
 import org.springframework.security.config.test.SpringTestContext;
 import org.springframework.security.config.test.SpringTestContextExtension;
+import org.springframework.security.config.util.InMemoryXmlWebApplicationContext;
 import org.springframework.security.util.FieldUtils;
 import org.springframework.test.web.servlet.MockMvc;
 
@@ -89,6 +91,16 @@ public class AuthenticationManagerBeanDefinitionParserTests {
 		assertThat(context.getBeansOfType(AuthenticationEventPublisher.class)).hasSize(1);
 	}
 
+	@Test
+	// gh-8767
+	public void multipleAuthenticationManagersAndDisableBeanDefinitionOverridingThenNoException() {
+		InMemoryXmlWebApplicationContext xmlContext = new InMemoryXmlWebApplicationContext(
+				CONTEXT + '\n' + CONTEXT_MULTI);
+		xmlContext.setAllowBeanDefinitionOverriding(false);
+		ConfigurableApplicationContext context = this.spring.context(xmlContext).getContext();
+		assertThat(context.getBeansOfType(AuthenticationManager.class)).hasSize(2);
+	}
+
 	@Test
 	public void eventsArePublishedByDefault() throws Exception {
 		ConfigurableApplicationContext appContext = this.spring.context(CONTEXT).getContext();