diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfiguration.java index afb14cf81c..c981c8d780 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfiguration.java @@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.ldap; import java.util.Collections; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -29,6 +30,7 @@ import org.springframework.core.env.Environment; import org.springframework.ldap.core.ContextSource; import org.springframework.ldap.core.LdapOperations; import org.springframework.ldap.core.LdapTemplate; +import org.springframework.ldap.core.support.DirContextAuthenticationStrategy; import org.springframework.ldap.core.support.LdapContextSource; /** @@ -45,8 +47,10 @@ public class LdapAutoConfiguration { @Bean @ConditionalOnMissingBean - public LdapContextSource ldapContextSource(LdapProperties properties, Environment environment) { + public LdapContextSource ldapContextSource(LdapProperties properties, Environment environment, + ObjectProvider dirContextAuthenticationStrategy) { LdapContextSource source = new LdapContextSource(); + dirContextAuthenticationStrategy.ifUnique(source::setAuthenticationStrategy); PropertyMapper propertyMapper = PropertyMapper.get().alwaysApplyingWhenNonNull(); propertyMapper.from(properties.getUsername()).to(source::setUserDn); propertyMapper.from(properties.getPassword()).to(source::setPassword); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfigurationTests.java index 796b3a99f5..7168020527 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/LdapAutoConfigurationTests.java @@ -24,11 +24,15 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.ldap.core.LdapTemplate; +import org.springframework.ldap.core.support.DirContextAuthenticationStrategy; import org.springframework.ldap.core.support.LdapContextSource; +import org.springframework.ldap.core.support.SimpleDirContextAuthenticationStrategy; import org.springframework.ldap.pool2.factory.PoolConfig; import org.springframework.ldap.pool2.factory.PooledContextSource; +import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; /** * Tests for {@link LdapAutoConfiguration}. @@ -113,6 +117,30 @@ class LdapAutoConfigurationTests { }); } + @Test + void contextSourceWithCustomUniqueDirContextAuthenticationStrategy() { + this.contextRunner.withUserConfiguration(CustomDirContextAuthenticationStrategy.class).run((context) -> { + assertThat(context).hasSingleBean(DirContextAuthenticationStrategy.class); + LdapContextSource contextSource = context.getBean(LdapContextSource.class); + assertThat(ReflectionTestUtils.getField(contextSource, "authenticationStrategy")) + .isSameAs(context.getBean("customDirContextAuthenticationStrategy")); + }); + } + + @Test + void contextSourceWithCustomNonUniqueDirContextAuthenticationStrategy() { + this.contextRunner.withUserConfiguration(CustomDirContextAuthenticationStrategy.class, + AnotherCustomDirContextAuthenticationStrategy.class).run((context) -> { + assertThat(context).hasBean("customDirContextAuthenticationStrategy") + .hasBean("anotherCustomDirContextAuthenticationStrategy"); + LdapContextSource contextSource = context.getBean(LdapContextSource.class); + assertThat(ReflectionTestUtils.getField(contextSource, "authenticationStrategy")) + .isNotSameAs(context.getBean("customDirContextAuthenticationStrategy")) + .isNotSameAs(context.getBean("anotherCustomDirContextAuthenticationStrategy")) + .isInstanceOf(SimpleDirContextAuthenticationStrategy.class); + }); + } + @Configuration(proxyBeanMethods = false) static class PooledContextSourceConfig { @@ -126,4 +154,24 @@ class LdapAutoConfigurationTests { } + @Configuration(proxyBeanMethods = false) + static class CustomDirContextAuthenticationStrategy { + + @Bean + DirContextAuthenticationStrategy customDirContextAuthenticationStrategy() { + return mock(DirContextAuthenticationStrategy.class); + } + + } + + @Configuration(proxyBeanMethods = false) + static class AnotherCustomDirContextAuthenticationStrategy { + + @Bean + DirContextAuthenticationStrategy anotherCustomDirContextAuthenticationStrategy() { + return mock(DirContextAuthenticationStrategy.class); + } + + } + } diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 60dd2d8d63..85ad9f4ee6 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -4445,6 +4445,7 @@ To connect to an LDAP server, make sure you declare a dependency on the `spring- If you need to customize connection settings, you can use the `spring.ldap.base` and `spring.ldap.base-environment` properties. An `LdapContextSource` is auto-configured based on these settings. +If a `DirContextAuthenticationStrategy` bean is available, it is associated to the auto-configured `LdapContextSource`. If you need to customize it, for instance to use a `PooledContextSource`, you can still inject the auto-configured `LdapContextSource`. Make sure to flag your customized `ContextSource` as `@Primary` so that the auto-configured `LdapTemplate` uses it.