Browse Source

Add support for LDAPS testing

Add to EmbeddedLdapProperties:
-boolean ldaps
-String sslBundleName
Create setLdapsListener method to create and set the LDAPS listener for the server.
Add test for new embedded LDAP setup.
Issue#48060

Signed-off-by: CatiaCorreia <catia.correia97@gmail.com>
pull/48315/head
CatiaCorreia 3 weeks ago
parent
commit
8d5bde94e0
  1. 33
      module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapAutoConfiguration.java
  2. 26
      module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapProperties.java
  3. 30
      module/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapAutoConfigurationTests.java
  4. BIN
      module/spring-boot-ldap/src/test/resources/org/springframework/boot/ldap/autoconfigure/embedded/keystore.jks
  5. BIN
      module/spring-boot-ldap/src/test/resources/org/springframework/boot/ldap/autoconfigure/embedded/keystore.pkcs12
  6. 23
      module/spring-boot-ldap/src/test/resources/org/springframework/boot/ldap/autoconfigure/embedded/rsa-cert.pem
  7. 28
      module/spring-boot-ldap/src/test/resources/org/springframework/boot/ldap/autoconfigure/embedded/rsa-key.pem

33
module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapAutoConfiguration.java

@ -22,10 +22,15 @@ import java.util.HashMap; @@ -22,10 +22,15 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocketFactory;
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.listener.InMemoryListenerConfig;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.ldap.sdk.schema.Schema;
import com.unboundid.ldif.LDIFReader;
import org.jspecify.annotations.Nullable;
@ -38,6 +43,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -38,6 +43,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
import org.springframework.boot.autoconfigure.condition.ConditionMessage.Builder;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
@ -47,6 +53,7 @@ import org.springframework.boot.context.properties.bind.Binder; @@ -47,6 +53,7 @@ import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.ldap.autoconfigure.LdapAutoConfiguration;
import org.springframework.boot.ldap.autoconfigure.LdapProperties;
import org.springframework.boot.ldap.autoconfigure.embedded.EmbeddedLdapAutoConfiguration.EmbeddedLdapAutoConfigurationRuntimeHints;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
@ -100,9 +107,13 @@ public final class EmbeddedLdapAutoConfiguration implements DisposableBean { @@ -100,9 +107,13 @@ public final class EmbeddedLdapAutoConfiguration implements DisposableBean {
config.addAdditionalBindCredentials(username, password);
}
setSchema(config);
InMemoryListenerConfig listenerConfig = InMemoryListenerConfig.createLDAPConfig("LDAP",
this.embeddedProperties.getPort());
config.setListenerConfigs(listenerConfig);
if (this.embeddedProperties.isLdaps()) {
this.setLdapsListener(applicationContext, config);
}
else {
config
.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("LDAP", this.embeddedProperties.getPort()));
}
this.server = new InMemoryDirectoryServer(config);
importLdif(this.server, applicationContext);
this.server.startListening();
@ -137,6 +148,22 @@ public final class EmbeddedLdapAutoConfiguration implements DisposableBean { @@ -137,6 +148,22 @@ public final class EmbeddedLdapAutoConfiguration implements DisposableBean {
}
}
@ConditionalOnBean(SslBundles.class)
private void setLdapsListener(ApplicationContext applicationContext, InMemoryDirectoryServerConfig config)
throws LDAPException {
if (StringUtils.hasText(this.embeddedProperties.getSslBundleName())) {
SslBundles sslBundles = applicationContext.getBean(SslBundles.class);
SSLContext sslContext = sslBundles.getBundle(this.embeddedProperties.getSslBundleName()).createSslContext();
SSLServerSocketFactory serverSocketFactory = sslContext.getServerSocketFactory();
SSLSocketFactory clientSocketFactory = sslContext.getSocketFactory();
config.setListenerConfigs(InMemoryListenerConfig.createLDAPSConfig("LDAPS", null,
this.embeddedProperties.getPort(), serverSocketFactory, clientSocketFactory));
}
else {
throw new LDAPException(ResultCode.PARAM_ERROR, "SslBundleName property not specified");
}
}
private void importLdif(InMemoryDirectoryServer server, ApplicationContext applicationContext) {
String location = this.embeddedProperties.getLdif();
if (StringUtils.hasText(location)) {

26
module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapProperties.java

@ -57,6 +57,16 @@ public class EmbeddedLdapProperties { @@ -57,6 +57,16 @@ public class EmbeddedLdapProperties {
*/
private String ldif = "classpath:schema.ldif";
/**
* Listener type.
*/
private boolean ldaps;
/**
* Embedded LDAPS client SSL bundle name.
*/
@Nullable private String sslBundleName;
/**
* Schema validation.
*/
@ -94,6 +104,22 @@ public class EmbeddedLdapProperties { @@ -94,6 +104,22 @@ public class EmbeddedLdapProperties {
this.ldif = ldif;
}
public boolean isLdaps() {
return this.ldaps;
}
public void setLdaps(boolean bool) {
this.ldaps = bool;
}
public @Nullable String getSslBundleName() {
return this.sslBundleName;
}
public void setSslBundleName(@Nullable String sslBundleName) {
this.sslBundleName = sslBundleName;
}
public Validation getValidation() {
return this.validation;
}

30
module/spring-boot-ldap/src/test/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapAutoConfigurationTests.java

@ -20,6 +20,8 @@ import java.lang.annotation.ElementType; @@ -20,6 +20,8 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.List;
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.sdk.BindResult;
@ -32,7 +34,9 @@ import org.junit.jupiter.api.Test; @@ -32,7 +34,9 @@ import org.junit.jupiter.api.Test;
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.ssl.SslAutoConfiguration;
import org.springframework.boot.ldap.autoconfigure.LdapAutoConfiguration;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.util.TestPropertyValues;
@ -54,7 +58,7 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -54,7 +58,7 @@ import static org.assertj.core.api.Assertions.assertThat;
class EmbeddedLdapAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EmbeddedLdapAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(EmbeddedLdapAutoConfiguration.class, SslAutoConfiguration.class));
@Test
void testSetDefaultPort() {
@ -66,6 +70,30 @@ class EmbeddedLdapAutoConfigurationTests { @@ -66,6 +70,30 @@ class EmbeddedLdapAutoConfigurationTests {
});
}
@Test
void testLdapsVersion() {
List<String> propertyValues = new ArrayList<>();
String location = "classpath:org/springframework/boot/ldap/autoconfigure/embedded/";
propertyValues.add("spring.ssl.bundle.pem.test.key.alias=alias1");
propertyValues.add("spring.ssl.bundle.pem.test.key.password=secret1");
propertyValues.add("spring.ssl.bundle.pem.test.keystore.certificate=" + location + "rsa-cert.pem");
propertyValues.add("spring.ssl.bundle.pem.test.keystore.keystore.private-key=" + location + "rsa-key.pem");
propertyValues.add("spring.ssl.bundle.pem.test.truststore.certificate=" + location + "rsa-cert.pem");
propertyValues.add("spring.ldap.embedded.port:1234");
propertyValues.add("spring.ldap.embedded.base-dn:dc=spring,dc=org");
propertyValues.add("spring.ldap.embedded.ldaps:true");
propertyValues.add("spring.ldap.embedded.sslBundleName:test");
propertyValues.add("spring.ldap.embedded.credential.username:uid=root");
propertyValues.add("spring.ldap.embedded.credential.password:boot");
this.contextRunner.withPropertyValues(propertyValues.toArray(String[]::new)).run((context) -> {
context.getBean(SslBundles.class);
InMemoryDirectoryServer server = context.getBean(InMemoryDirectoryServer.class);
assertThat(server.getListenPort()).isEqualTo(1234);
BindResult result = server.bind("uid=root", "boot");
assertThat(result).isNotNull();
});
}
@Test
void testRandomPortWithEnvironment() {
this.contextRunner.withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org").run((context) -> {

BIN
module/spring-boot-ldap/src/test/resources/org/springframework/boot/ldap/autoconfigure/embedded/keystore.jks

Binary file not shown.

BIN
module/spring-boot-ldap/src/test/resources/org/springframework/boot/ldap/autoconfigure/embedded/keystore.pkcs12

Binary file not shown.

23
module/spring-boot-ldap/src/test/resources/org/springframework/boot/ldap/autoconfigure/embedded/rsa-cert.pem

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID1zCCAr+gAwIBAgIUNM5QQv8IzVQsgSmmdPQNaqyzWs4wDQYJKoZIhvcNAQEL
BQAwezELMAkGA1UEBhMCWFgxEjAQBgNVBAgMCVN0YXRlTmFtZTERMA8GA1UEBwwI
Q2l0eU5hbWUxFDASBgNVBAoMC0NvbXBhbnlOYW1lMRswGQYDVQQLDBJDb21wYW55
U2VjdGlvbk5hbWUxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0yMzA5MTExMjExNTha
Fw0zMzA5MDgxMjExNThaMHsxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5h
bWUxETAPBgNVBAcMCENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkG
A1UECwwSQ29tcGFueVNlY3Rpb25OYW1lMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCfdkeEiCk+5mpXUhJ1FLmOCx6/
jAHHaDxZ8hIpyp/c4ZAqFX5uamP08jL056kRKL4RRoUamNWdt0dgpHqds/84pb+3
OlCVjnFvzGVrvRwdrrQA2mda0BDm2Qnb0r9IhZr7tBpursbDsIC1U6zk1iwrbiO3
hu0/9uXlMWt49nccTDOpTtuhYUPEA3+NQFqUCwHrd8H9j+BQD5lf4RhoE6krDdV1
JD8qOns+uD6IKn0xfyPHmy8LD0mM5Rch6J13TZnH1yeFT8Y0ZnAPuwXHO5BNw504
3Kt/das3NvV+4Qq0qQ08NFK+vmoooP11uIcZb8gUaMgmRINL4P3TOhyA1ueXAgMB
AAGjUzBRMB0GA1UdDgQWBBRHYz8OjqU/4JZMegJaN/jQbdj4MjAfBgNVHSMEGDAW
gBRHYz8OjqU/4JZMegJaN/jQbdj4MjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
DQEBCwUAA4IBAQBr9zqlNx7Mr1ordGfhk+xFrDtyBnk1vXbwVdnog66REqpPLH+K
MfCKdj6wFoPa8ZjPb4VYFp2DvMxVXtFMzqGfLjYJPqefEzQCleOcA5aiE/ENIaaD
ybYh99V5CsFAqyKuHLBFEzeYJ028SR3QsCISom0k/Fh6y2IwHJJEHykjqJKvL4bb
V0IJjcmYjEZbTvpjFKznvaFiOUv+8L7jHQ1/Yf+9c3C8gSjdUfv88m17pqYXd+Ds
HEmfmNNjht130UyjNCITmLVXyy5p35vWmdf95U3uEbJSnNVtXH8qRmN9oK9mUpDb
ngX6JBJI7fw7tXoqWSLHNiBODM88fUlQSho8
-----END CERTIFICATE-----

28
module/spring-boot-ldap/src/test/resources/org/springframework/boot/ldap/autoconfigure/embedded/rsa-key.pem

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCfdkeEiCk+5mpX
UhJ1FLmOCx6/jAHHaDxZ8hIpyp/c4ZAqFX5uamP08jL056kRKL4RRoUamNWdt0dg
pHqds/84pb+3OlCVjnFvzGVrvRwdrrQA2mda0BDm2Qnb0r9IhZr7tBpursbDsIC1
U6zk1iwrbiO3hu0/9uXlMWt49nccTDOpTtuhYUPEA3+NQFqUCwHrd8H9j+BQD5lf
4RhoE6krDdV1JD8qOns+uD6IKn0xfyPHmy8LD0mM5Rch6J13TZnH1yeFT8Y0ZnAP
uwXHO5BNw5043Kt/das3NvV+4Qq0qQ08NFK+vmoooP11uIcZb8gUaMgmRINL4P3T
OhyA1ueXAgMBAAECggEAPK1LqmULWMlhdoeeyVlQ//lAQn+6X4/MwycG/UsCSJC2
BCV4nfgyv853UFRkM0jPBhDQ7h1wz1ohuWbs11xaBcqgKE7ywe3ZQULD5tqnO64y
BU8V2+rnO4gjpbdMHQLlxdgy5KHxtR3Q4+6Kj+rlFMOMqLWZSmke8na7H+SczzGf
+dZO4LRTbjGmFdUidehovm2icSM8OdU2w3FHlFRu2NBsTHGeAhRw86Yw24KfJp4R
GSDQIBdwp1wCs5w7w4zPjxS7Zi+Uwspyq31KDJwyfK2O1WLI05bQ6FLqVRD/xy+Y
b4WCse1O08SYWze2No915LB07sokgmomr3//bOwuEQKBgQDPBrPQXokn0BoTlgsa
JohgWzQ5P9u/2WY+u2SG/xgNEx0s+lk/AmAH80wsBJ68FV6z5Non7TzD7xCsf2HJ
3cP/EHl2ngTctz/eqpCcS5UPZBHmay60q6WKIkH/3ml7c0UhlqSqS3EDVyEe05hk
msWAN+fV4ajVlhWgiUZRVdxMpwKBgQDFLyPBOEn6zLOHfkQWcibVf8s2LTe76R/S
8Gk3jbk5mimR3vNm0L/rHqGwl75rOuFiFOHVkfuY9Dawaht0QnagjayT5hDqr6aD
s5Chyoy9qpXnfnqOgk6rQZqj+/ODkjqEkBdRCKWvCVnDIi3Au2kS3QIc4iTsGrBW
ygZdbxM7kQKBgEuzS7T5nHVuZtqaltytElkJgIMekqAIQpbVtuCWDplZT+XOdSvR
FoRRtpyx48kql0J4gDzxRrLui85Hld5WtQBjacax6V07tKMbA13jVVIXaWQz9RQj
X5ivBisljLSTZcfuaa/LfjuWdIntHWBMJ8PGrYNLzIytIKNfDtNW7gMpAoGAIRZQ
5JpCZ7Azq9e3KyEKfSbNfZDG2mQ679Vhgm3ol87TjOOhai47FgP008IStMGTkja4
0nKFilvoVV/orXB9oWFEhSjEy+yff1gBO/TV+vmF3+tsOz+IXdpLTZr4eKpv4VCg
aPuPebiS9Fhm3wFTl1O4iAo2cdvknRuXR9RcoNECgYADksGk1lJGW5kMIMJ+6os+
CJdGnJiX7XsnM0VzkagswnqDe03SqkJuFOmIp96eitxLT4EfB+585pYQRSy2fyJX
WR2AAnC7oqUcQFkgDt9WBZAazI6aLXYO+trRoGKuWynGM8mjetr5C75g0auj4lsN
rGiie2UnjshJ67FrG4kZoA==
-----END PRIVATE KEY-----
Loading…
Cancel
Save