Skip to content

Commit db5e542

Browse files
kagofrwinch
authored andcommitted
#3912 lazyBean method respects @primary annotation
1 parent b2c2f84 commit db5e542

File tree

2 files changed

+49
-11
lines changed

2 files changed

+49
-11
lines changed

config/src/main/java/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfiguration.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,15 @@
1515
*/
1616
package org.springframework.security.config.annotation.authentication.configuration;
1717

18-
import java.util.Arrays;
19-
import java.util.Collections;
20-
import java.util.List;
21-
import java.util.Map;
22-
import java.util.concurrent.atomic.AtomicBoolean;
23-
2418
import org.apache.commons.logging.Log;
2519
import org.apache.commons.logging.LogFactory;
26-
2720
import org.springframework.aop.framework.ProxyFactoryBean;
2821
import org.springframework.aop.target.LazyInitTargetSource;
2922
import org.springframework.beans.factory.BeanFactoryUtils;
3023
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
3124
import org.springframework.beans.factory.annotation.Autowired;
3225
import org.springframework.context.ApplicationContext;
26+
import org.springframework.context.ConfigurableApplicationContext;
3327
import org.springframework.context.annotation.Bean;
3428
import org.springframework.context.annotation.Configuration;
3529
import org.springframework.context.annotation.Import;
@@ -49,6 +43,13 @@
4943
import org.springframework.security.crypto.password.PasswordEncoder;
5044
import org.springframework.util.Assert;
5145

46+
import java.util.Arrays;
47+
import java.util.Collections;
48+
import java.util.List;
49+
import java.util.Map;
50+
import java.util.concurrent.atomic.AtomicBoolean;
51+
import java.util.stream.Collectors;
52+
5253
/**
5354
* Exports the authentication {@link Configuration}
5455
*
@@ -151,10 +152,23 @@ private <T> T lazyBean(Class<T> interfaceName) {
151152
if (beanNamesForType.length == 0) {
152153
return null;
153154
}
154-
Assert.isTrue(beanNamesForType.length == 1,
155-
() -> "Expecting to only find a single bean for type " + interfaceName
156-
+ ", but found " + Arrays.asList(beanNamesForType));
157-
lazyTargetSource.setTargetBeanName(beanNamesForType[0]);
155+
String beanName;
156+
if (beanNamesForType.length > 1) {
157+
List<String> primaryBeanNames = Arrays.stream(beanNamesForType)
158+
.filter(i -> applicationContext instanceof ConfigurableApplicationContext)
159+
.filter(n -> ((ConfigurableApplicationContext) applicationContext).getBeanFactory().getBeanDefinition(n).isPrimary())
160+
.collect(Collectors.toList());
161+
162+
Assert.isTrue(primaryBeanNames.size() != 0, () -> "Found " + beanNamesForType.length
163+
+ " beans for type " + interfaceName + ", but none marked as primary");
164+
Assert.isTrue(primaryBeanNames.size() == 1, () -> "Found " + primaryBeanNames.size()
165+
+ " beans for type " + interfaceName + " marked as primary");
166+
beanName = primaryBeanNames.get(0);
167+
} else {
168+
beanName = beanNamesForType[0];
169+
}
170+
171+
lazyTargetSource.setTargetBeanName(beanName);
158172
lazyTargetSource.setBeanFactory(applicationContext);
159173
ProxyFactoryBean proxyFactory = new ProxyFactoryBean();
160174
proxyFactory = objectPostProcessor.postProcess(proxyFactory);

config/src/test/java/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfigurationTests.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.springframework.context.annotation.Bean;
2424
import org.springframework.context.annotation.Configuration;
2525
import org.springframework.context.annotation.Import;
26+
import org.springframework.context.annotation.Primary;
2627
import org.springframework.core.Ordered;
2728
import org.springframework.core.annotation.Order;
2829
import org.springframework.security.access.annotation.Secured;
@@ -506,4 +507,27 @@ static class UsesServiceMethodSecurityConfig {
506507
@Autowired
507508
Service service;
508509
}
510+
511+
@Test
512+
public void getAuthenticationManagerBeanWhenMultipleDefinedAndOnePrimaryThenNoException() throws Exception {
513+
this.spring.register(MultipleAuthenticationManagerBeanConfig.class).autowire();
514+
this.spring.getContext().getBeanFactory().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
515+
}
516+
517+
@Configuration
518+
@Import(AuthenticationConfiguration.class)
519+
static class MultipleAuthenticationManagerBeanConfig {
520+
521+
@Bean
522+
@Primary
523+
public AuthenticationManager manager1() {
524+
return mock(AuthenticationManager.class);
525+
}
526+
527+
@Bean
528+
public AuthenticationManager manager2() {
529+
return mock(AuthenticationManager.class);
530+
}
531+
532+
}
509533
}

0 commit comments

Comments
 (0)