Merge pull request #11764 from eddumelendez
* pr/11764: Polish 'Add support for multi baseDn; Add support for multi baseDn Migrate LDAP tests to use ApplicationContextRunner
This commit is contained in:
commit
b8e220c4f4
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -33,7 +33,6 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
|||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.ldap.LdapProperties;
|
||||
import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapProperties.Credential;
|
||||
|
|
@ -50,6 +49,7 @@ import org.springframework.core.env.PropertySource;
|
|||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.ldap.core.ContextSource;
|
||||
import org.springframework.ldap.core.support.LdapContextSource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
|
|
@ -64,7 +64,6 @@ import org.springframework.util.StringUtils;
|
|||
@EnableConfigurationProperties({ LdapProperties.class, EmbeddedLdapProperties.class })
|
||||
@AutoConfigureBefore(LdapAutoConfiguration.class)
|
||||
@ConditionalOnClass(InMemoryDirectoryServer.class)
|
||||
@ConditionalOnProperty(prefix = "spring.ldap.embedded", name = "base-dn")
|
||||
public class EmbeddedLdapAutoConfiguration {
|
||||
|
||||
private static final String PROPERTY_SOURCE_NAME = "ldap.ports";
|
||||
|
|
@ -86,6 +85,7 @@ public class EmbeddedLdapAutoConfiguration {
|
|||
this.properties = properties;
|
||||
this.applicationContext = applicationContext;
|
||||
this.environment = environment;
|
||||
Assert.notEmpty(this.embeddedProperties.getBaseDn(), "No baseDn found.");
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
@ -103,8 +103,8 @@ public class EmbeddedLdapAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
public InMemoryDirectoryServer directoryServer() throws LDAPException {
|
||||
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(
|
||||
this.embeddedProperties.getBaseDn());
|
||||
String[] baseDn = this.embeddedProperties.getBaseDn().toArray(new String[0]);
|
||||
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(baseDn);
|
||||
if (hasCredentials(this.embeddedProperties.getCredential())) {
|
||||
config.addAdditionalBindCredentials(
|
||||
this.embeddedProperties.getCredential().getUsername(),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -16,7 +16,11 @@
|
|||
|
||||
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.context.properties.bind.convert.Delimiter;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
|
|
@ -40,9 +44,10 @@ public class EmbeddedLdapProperties {
|
|||
private Credential credential = new Credential();
|
||||
|
||||
/**
|
||||
* The base DN.
|
||||
* List of base DN.
|
||||
*/
|
||||
private String baseDn;
|
||||
@Delimiter(Delimiter.NONE)
|
||||
private List<String> baseDn = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Schema (LDIF) script resource reference.
|
||||
|
|
@ -70,11 +75,11 @@ public class EmbeddedLdapProperties {
|
|||
this.credential = credential;
|
||||
}
|
||||
|
||||
public String getBaseDn() {
|
||||
public List<String> getBaseDn() {
|
||||
return this.baseDn;
|
||||
}
|
||||
|
||||
public void setBaseDn(String baseDn) {
|
||||
public void setBaseDn(List<String> baseDn) {
|
||||
this.baseDn = baseDn;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -21,14 +21,14 @@ import com.unboundid.ldap.sdk.BindResult;
|
|||
import com.unboundid.ldap.sdk.DN;
|
||||
import com.unboundid.ldap.sdk.LDAPConnection;
|
||||
import com.unboundid.ldap.sdk.LDAPException;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.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.data.ldap.LdapDataAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration;
|
||||
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;
|
||||
|
|
@ -44,121 +44,145 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
*/
|
||||
public class EmbeddedLdapAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(EmbeddedLdapAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void testSetDefaultPort() {
|
||||
load("spring.ldap.embedded.port:1234",
|
||||
"spring.ldap.embedded.base-dn:dc=spring,dc=org");
|
||||
InMemoryDirectoryServer server = this.context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
assertThat(server.getListenPort()).isEqualTo(1234);
|
||||
this.contextRunner.withPropertyValues("spring.ldap.embedded.port:1234",
|
||||
"spring.ldap.embedded.base-dn:dc=spring,dc=org").run(context -> {
|
||||
InMemoryDirectoryServer server = context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
assertThat(server.getListenPort()).isEqualTo(1234);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandomPortWithEnvironment() {
|
||||
load("spring.ldap.embedded.base-dn:dc=spring,dc=org");
|
||||
InMemoryDirectoryServer server = this.context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
assertThat(server.getListenPort()).isEqualTo(this.context.getEnvironment()
|
||||
.getProperty("local.ldap.port", Integer.class));
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org")
|
||||
.run(context -> {
|
||||
InMemoryDirectoryServer server = context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
assertThat(server.getListenPort()).isEqualTo(context.getEnvironment()
|
||||
.getProperty("local.ldap.port", Integer.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandomPortWithValueAnnotation() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
TestPropertyValues.of("spring.ldap.embedded.base-dn:dc=spring,dc=org")
|
||||
.applyTo(this.context);
|
||||
this.context.register(EmbeddedLdapAutoConfiguration.class,
|
||||
.applyTo(context);
|
||||
context.register(EmbeddedLdapAutoConfiguration.class,
|
||||
LdapClientConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
LDAPConnection connection = this.context.getBean(LDAPConnection.class);
|
||||
assertThat(connection.getConnectedPort()).isEqualTo(this.context.getEnvironment()
|
||||
.getProperty("local.ldap.port", Integer.class));
|
||||
context.refresh();
|
||||
LDAPConnection connection = context.getBean(LDAPConnection.class);
|
||||
assertThat(connection.getConnectedPort()).isEqualTo(
|
||||
context.getEnvironment().getProperty("local.ldap.port", Integer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetCredentials() throws LDAPException {
|
||||
load("spring.ldap.embedded.base-dn:dc=spring,dc=org",
|
||||
"spring.ldap.embedded.credential.username:uid=root",
|
||||
"spring.ldap.embedded.credential.password:boot");
|
||||
InMemoryDirectoryServer server = this.context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
BindResult result = server.bind("uid=root", "boot");
|
||||
assertThat(result).isNotNull();
|
||||
public void testSetCredentials() {
|
||||
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 -> {
|
||||
InMemoryDirectoryServer server = context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
BindResult result = server.bind("uid=root", "boot");
|
||||
assertThat(result).isNotNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetPartitionSuffix() throws LDAPException {
|
||||
load("spring.ldap.embedded.base-dn:dc=spring,dc=org");
|
||||
InMemoryDirectoryServer server = this.context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
assertThat(server.getBaseDNs()).containsExactly(new DN("dc=spring,dc=org"));
|
||||
public void testSetPartitionSuffix() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org")
|
||||
.run(context -> {
|
||||
InMemoryDirectoryServer server = context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
assertThat(server.getBaseDNs())
|
||||
.containsExactly(new DN("dc=spring,dc=org"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetLdifFile() throws LDAPException {
|
||||
load("spring.ldap.embedded.base-dn:dc=spring,dc=org");
|
||||
InMemoryDirectoryServer server = this.context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
assertThat(server.countEntriesBelow("ou=company1,c=Sweden,dc=spring,dc=org"))
|
||||
.isEqualTo(5);
|
||||
public void testSetLdifFile() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org")
|
||||
.run(context -> {
|
||||
InMemoryDirectoryServer server = context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
assertThat(server
|
||||
.countEntriesBelow("ou=company1,c=Sweden,dc=spring,dc=org"))
|
||||
.isEqualTo(5);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryEmbeddedLdap() {
|
||||
TestPropertyValues.of("spring.ldap.embedded.base-dn:dc=spring,dc=org")
|
||||
.applyTo(this.context);
|
||||
this.context.register(EmbeddedLdapAutoConfiguration.class,
|
||||
LdapAutoConfiguration.class, LdapDataAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBeanNamesForType(LdapTemplate.class).length)
|
||||
.isEqualTo(1);
|
||||
LdapTemplate ldapTemplate = this.context.getBean(LdapTemplate.class);
|
||||
assertThat(ldapTemplate.list("ou=company1,c=Sweden,dc=spring,dc=org")).hasSize(4);
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org")
|
||||
.withConfiguration(AutoConfigurations.of(LdapAutoConfiguration.class,
|
||||
LdapDataAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeanNamesForType(LdapTemplate.class).length)
|
||||
.isEqualTo(1);
|
||||
LdapTemplate ldapTemplate = context.getBean(LdapTemplate.class);
|
||||
assertThat(ldapTemplate.list("ou=company1,c=Sweden,dc=spring,dc=org"))
|
||||
.hasSize(4);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableSchemaValidation() throws LDAPException {
|
||||
load("spring.ldap.embedded.validation.enabled:false",
|
||||
"spring.ldap.embedded.base-dn:dc=spring,dc=org");
|
||||
InMemoryDirectoryServer server = this.context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
assertThat(server.getSchema()).isNull();
|
||||
public void testDisableSchemaValidation() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.ldap.embedded.validation.enabled:false",
|
||||
"spring.ldap.embedded.base-dn:dc=spring,dc=org")
|
||||
.run(context -> {
|
||||
InMemoryDirectoryServer server = context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
assertThat(server.getSchema()).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomSchemaValidation() throws LDAPException {
|
||||
load("spring.ldap.embedded.validation.schema:classpath:custom-schema.ldif",
|
||||
public void testCustomSchemaValidation() {
|
||||
this.contextRunner.withPropertyValues(
|
||||
"spring.ldap.embedded.validation.schema:classpath:custom-schema.ldif",
|
||||
"spring.ldap.embedded.ldif:classpath:custom-schema-sample.ldif",
|
||||
"spring.ldap.embedded.base-dn:dc=spring,dc=org");
|
||||
InMemoryDirectoryServer server = this.context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
"spring.ldap.embedded.base-dn:dc=spring,dc=org").run(context -> {
|
||||
InMemoryDirectoryServer server = context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
|
||||
assertThat(server.getSchema().getObjectClass("exampleAuxiliaryClass"))
|
||||
.isNotNull();
|
||||
assertThat(server.getSchema().getAttributeType("exampleAttributeName"))
|
||||
.isNotNull();
|
||||
assertThat(server.getSchema().getObjectClass("exampleAuxiliaryClass"))
|
||||
.isNotNull();
|
||||
assertThat(
|
||||
server.getSchema().getAttributeType("exampleAttributeName"))
|
||||
.isNotNull();
|
||||
});
|
||||
}
|
||||
|
||||
private void load(String... properties) {
|
||||
TestPropertyValues.of(properties).applyTo(this.context);
|
||||
this.context.register(EmbeddedLdapAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
@Test
|
||||
public void testMultiBaseDn() {
|
||||
this.contextRunner
|
||||
.withPropertyValues(
|
||||
"spring.ldap.embedded.ldif:classpath:schema-multi-basedn.ldif",
|
||||
"spring.ldap.embedded.base-dn[0]:dc=spring,dc=org",
|
||||
"spring.ldap.embedded.base-dn[1]:dc=pivotal,dc=io")
|
||||
.run(context -> {
|
||||
InMemoryDirectoryServer server = context
|
||||
.getBean(InMemoryDirectoryServer.class);
|
||||
assertThat(server
|
||||
.countEntriesBelow("ou=company1,c=Sweden,dc=spring,dc=org"))
|
||||
.isEqualTo(5);
|
||||
assertThat(server.countEntriesBelow("c=Sweden,dc=pivotal,dc=io"))
|
||||
.isEqualTo(2);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
|
|
|||
|
|
@ -0,0 +1,114 @@
|
|||
dn: dc=spring,dc=org
|
||||
objectclass: top
|
||||
objectclass: domain
|
||||
objectclass: extensibleObject
|
||||
dc: spring
|
||||
|
||||
dn: ou=groups,dc=spring,dc=org
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: groups
|
||||
|
||||
dn: cn=ROLE_USER,ou=groups,dc=spring,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfUniqueNames
|
||||
cn: ROLE_USER
|
||||
uniqueMember: cn=Some Person,ou=company1,c=Sweden,dc=spring,dc=org
|
||||
uniqueMember: cn=Some Person2,ou=company1,c=Sweden,dc=spring,dc=org
|
||||
uniqueMember: cn=Some Person,ou=company1,c=Sweden,dc=spring,dc=org
|
||||
uniqueMember: cn=Some Person3,ou=company1,c=Sweden,dc=spring,dc=org
|
||||
|
||||
dn: cn=ROLE_ADMIN,ou=groups,dc=spring,dc=org
|
||||
objectclass: top
|
||||
objectclass: groupOfUniqueNames
|
||||
cn: ROLE_ADMIN
|
||||
uniqueMember: cn=Some Person2,ou=company1,c=Sweden,dc=spring,dc=org
|
||||
|
||||
dn: c=Sweden,dc=spring,dc=org
|
||||
objectclass: top
|
||||
objectclass: country
|
||||
c: Sweden
|
||||
description: The country of Sweden
|
||||
|
||||
dn: ou=company1,c=Sweden,dc=spring,dc=org
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: company1
|
||||
description: First company in Sweden
|
||||
|
||||
dn: cn=Some Person,ou=company1,c=Sweden,dc=spring,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person
|
||||
userPassword: password
|
||||
cn: Some Person
|
||||
sn: Person
|
||||
description: Sweden, Company1, Some Person
|
||||
telephoneNumber: +46 555-123456
|
||||
|
||||
dn: cn=Some Person2,ou=company1,c=Sweden,dc=spring,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person2
|
||||
userPassword: password
|
||||
cn: Some Person2
|
||||
sn: Person2
|
||||
description: Sweden, Company1, Some Person2
|
||||
telephoneNumber: +46 555-654321
|
||||
|
||||
dn: cn=Some Person3,ou=company1,c=Sweden,dc=spring,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person3
|
||||
userPassword: password
|
||||
cn: Some Person3
|
||||
sn: Person3
|
||||
description: Sweden, Company1, Some Person3
|
||||
telephoneNumber: +46 555-123654
|
||||
|
||||
dn: cn=Some Person4,ou=company1,c=Sweden,dc=spring,dc=org
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person4
|
||||
userPassword: password
|
||||
cn: Some Person
|
||||
sn: Person
|
||||
description: Sweden, Company1, Some Person
|
||||
telephoneNumber: +46 555-456321
|
||||
|
||||
dn: dc=pivotal,dc=io
|
||||
objectclass: top
|
||||
objectclass: domain
|
||||
objectclass: extensibleObject
|
||||
dc: pivotal
|
||||
|
||||
dn: ou=groups,dc=pivotal,dc=io
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: groups
|
||||
|
||||
dn: c=Sweden,dc=pivotal,dc=io
|
||||
objectclass: top
|
||||
objectclass: country
|
||||
c: Sweden
|
||||
description:The country of Sweden
|
||||
|
||||
dn: cn=Some Random Person,c=Sweden,dc=pivotal,dc=io
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.random.person
|
||||
userPassword: password
|
||||
cn: Some Random Person
|
||||
sn: Person
|
||||
description: Sweden, Pivotal, Some Random Person
|
||||
telephoneNumber: +46 555-123456
|
||||
|
|
@ -4417,6 +4417,32 @@ follows:
|
|||
spring.ldap.embedded.base-dn=dc=spring,dc=io
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
It is possible to define multiple base-dn values, however, since distinguished names
|
||||
usually contain commas, they must be defined using the correct notation.
|
||||
|
||||
In yaml files, you can use the yaml list notation:
|
||||
|
||||
[source,yaml,indent=0]
|
||||
----
|
||||
spring.ldap.embedded.base-dn:
|
||||
- dc=spring,dc=io
|
||||
- dc=pivotal,dc=io
|
||||
----
|
||||
|
||||
in properties files, you must include the index as part of the property name:
|
||||
|
||||
[source,properties,indent=0]
|
||||
----
|
||||
spring.ldap.embedded.base-dn[0]=dc=spring,dc=io
|
||||
spring.ldap.embedded.base-dn[1]=dc=pivotal,dc=io
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
WARNING: `spring.ldap.embedded.base-dn` supports multi base DN, so it must define as follows `spring.ldap.embedded.base-dn[0]=dc=spring,dc=io`
|
||||
|
||||
By default, the server starts on a random port and triggers the regular LDAP support.
|
||||
There is no need to specify a `spring.ldap.urls` property.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue