Allow Embedded directory to be used without spring-data-ldap

See gh-20223
This commit is contained in:
Frank Schmager 2020-02-18 12:04:57 -05:00 committed by Stephane Nicoll
parent 2d5a55fb0d
commit a92c57c07d
3 changed files with 72 additions and 21 deletions

View File

@ -41,7 +41,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration;
import org.springframework.boot.autoconfigure.ldap.LdapProperties;
import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapProperties.Credential;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
@ -58,6 +57,7 @@ import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.util.StringUtils;
@ -76,6 +76,8 @@ import org.springframework.util.StringUtils;
@Conditional(EmbeddedLdapAutoConfiguration.EmbeddedLdapCondition.class)
public class EmbeddedLdapAutoConfiguration {
private static final String DIRECTORY_SERVER_BEAN_NAME = "directoryServer";
private static final String PROPERTY_SOURCE_NAME = "ldap.ports";
private final EmbeddedLdapProperties embeddedProperties;
@ -86,24 +88,11 @@ public class EmbeddedLdapAutoConfiguration {
this.embeddedProperties = embeddedProperties;
}
@Bean
@DependsOn("directoryServer")
@ConditionalOnMissingBean
public LdapContextSource ldapContextSource(Environment environment, LdapProperties properties) {
LdapContextSource source = new LdapContextSource();
if (hasCredentials(this.embeddedProperties.getCredential())) {
source.setUserDn(this.embeddedProperties.getCredential().getUsername());
source.setPassword(this.embeddedProperties.getCredential().getPassword());
}
source.setUrls(properties.determineUrls(environment));
return source;
}
@Bean
@Bean(name = DIRECTORY_SERVER_BEAN_NAME)
public InMemoryDirectoryServer directoryServer(ApplicationContext applicationContext) throws LDAPException {
String[] baseDn = StringUtils.toStringArray(this.embeddedProperties.getBaseDn());
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(baseDn);
if (hasCredentials(this.embeddedProperties.getCredential())) {
if (this.embeddedProperties.hasCredential()) {
config.addAdditionalBindCredentials(this.embeddedProperties.getCredential().getUsername(),
this.embeddedProperties.getCredential().getPassword());
}
@ -140,9 +129,7 @@ public class EmbeddedLdapAutoConfiguration {
}
}
private boolean hasCredentials(Credential credential) {
return StringUtils.hasText(credential.getUsername()) && StringUtils.hasText(credential.getPassword());
}
private void importLdif(ApplicationContext applicationContext) throws LDAPException {
String location = this.embeddedProperties.getLdif();
@ -210,4 +197,25 @@ public class EmbeddedLdapAutoConfiguration {
}
/**
* Creates an {@link LdapContextSource} for use with Embedded LDAP.
*/
@Configuration
@ConditionalOnClass(ContextSource.class)
static class EmbeddedLdapContextConfiguration {
@Bean
@DependsOn(DIRECTORY_SERVER_BEAN_NAME)
@ConditionalOnMissingBean
public LdapContextSource ldapContextSource(Environment environment, LdapProperties properties, EmbeddedLdapProperties embeddedProperties) {
LdapContextSource source = new LdapContextSource();
if (embeddedProperties.hasCredential()) {
source.setUserDn(embeddedProperties.getCredential().getUsername());
source.setPassword(embeddedProperties.getCredential().getPassword());
}
source.setUrls(properties.determineUrls(environment));
return source;
}
}
}

View File

@ -18,10 +18,10 @@ package org.springframework.boot.autoconfigure.ldap.embedded;
import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.convert.Delimiter;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;
/**
* Configuration properties for Embedded LDAP.
@ -75,6 +75,10 @@ public class EmbeddedLdapProperties {
this.credential = credential;
}
public boolean hasCredential() {
return credential != null && StringUtils.hasText(credential.getUsername()) && StringUtils.hasText(credential.getPassword());
}
public List<String> getBaseDn() {
return this.baseDn;
}

View File

@ -22,19 +22,23 @@ import com.unboundid.ldap.sdk.DN;
import com.unboundid.ldap.sdk.LDAPConnection;
import com.unboundid.ldap.sdk.LDAPException;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
/**
* Tests for {@link EmbeddedLdapAutoConfiguration}
@ -146,6 +150,41 @@ class EmbeddedLdapAutoConfigurationTests {
});
}
@Test
void testLdapContextSourceWithCredentials() {
this.contextRunner.withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org",
"spring.ldap.embedded.credential.username:uid=root", "spring.ldap.embedded.credential.password:boot")
.run(context -> {
LdapContextSource ldapContextSource = context.getBean(LdapContextSource.class);
assertThat(ldapContextSource.getUserDn()).isEqualTo("uid=root");
assertThat(ldapContextSource.getUrls()).isNotEmpty();
});
}
@Test
void testLdapContextSourceWithoutCredentials() {
this.contextRunner.withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org")
.run(context -> {
LdapContextSource ldapContextSource = context.getBean(LdapContextSource.class);
assertThat(ldapContextSource.getUserDn()).isEmpty();
assertThat(ldapContextSource.getUrls()).isNotEmpty();
});
}
@Test
void testNoLdapContextSourceWithoutContextSourceClass() {
this.contextRunner
.withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org")
.withClassLoader(new FilteredClassLoader(ContextSource.class))
.run(context -> {
NoSuchBeanDefinitionException expectedException =
new NoSuchBeanDefinitionException(LdapContextSource.class);
assertThatThrownBy(()-> context.getBean(LdapContextSource.class))
.isInstanceOf(expectedException.getClass())
.hasMessage(expectedException.getMessage());
});
}
@Configuration(proxyBeanMethods = false)
static class LdapClientConfiguration {