Running OpenDJ-based Embedded LDAP in a Spring Boot Application
Introduction
In this article, we will set up a Spring Boot application with embedded LDAP based on an open source LDAP server. OpenDJ. This may be needed both for tests and for productive use. For example, for authentication via LDAP.
Creating a Project
Create an empty Spring Boot project using the Spring Initializer website or manually. Add the dependency opendj-embedded
to file pom.xml
Spring Boot Applications
<dependency>
<groupId>org.openidentityplatform.opendj</groupId>
<artifactId>opendj-embedded</artifactId>
<version>4.6.4</version>
</dependency>
Add Java 8 compatibility arguments to project properties
<properties>
...
<jvm.compatibility.args>
--add-exports java.base/sun.security.tools.keytool=ALL-UNNAMED
--add-exports java.base/sun.security.x509=ALL-UNNAMED
</jvm.compatibility.args>
</properties>
And write these arguments in spring-boot-maven-plugin
:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jvmArguments>${jvm.compatibility.args}</jvmArguments>
</configuration>
</plugin>
Add the Embedded OpenDJ bean to your Spring Boot application.
@Bean
public EmbeddedOpenDJ embeddedOpenDJ() {
EmbeddedOpenDJ embeddedOpenDJ = new EmbeddedOpenDJ();
embeddedOpenDJ.run();
return embeddedOpenDJ;
}
Basically, that's all you need to run the built-in OpenDJ. There are some nuances left. Let's look at how you can change the OpenDJ configuration.
Changing the Default Configuration
Create a new configuration class that inherits from org.openidentityplatform.opendj.embedded.Config
and overload the required properties, such as baseDN and admin password:
@Configuration
public class OpenDJConfiguration extends Config {
@Override
@Value("${opendj.basedn:dc=example,dc=openidentityplatform,dc=org}")
public void setBaseDN(String baseDN) {
super.setBaseDN(baseDN);
}
@Override
@Value("${opendj.adminpwd:passw0rd}")
public void setAdminPassword(String adminPassword) {
super.setAdminPassword(adminPassword);
}
}
Add configuration to bean initialization EmbeddedOpenDJ
@Bean
public EmbeddedOpenDJ embeddedOpenDJ(OpenDJConfiguration configuration) throws IOException, EmbeddedDirectoryServerException {
EmbeddedOpenDJ embeddedOpenDJ = new EmbeddedOpenDJ(configuration);
embeddedOpenDJ.run();
return embeddedOpenDJ;
}
Import data
For demonstration purposes, we import the initial ldif data from the string.
@Bean
public EmbeddedOpenDJ embeddedOpenDJ(OpenDJConfiguration configuration) throws IOException, EmbeddedDirectoryServerException {
EmbeddedOpenDJ embeddedOpenDJ = new EmbeddedOpenDJ(configuration);
embeddedOpenDJ.run();
String data = """
dn: dc=example,dc=openidentityplatform,dc=org
objectClass: top
objectClass: domain
dc: example
dn: ou=people,dc=example,dc=openidentityplatform,dc=org
objectclass: top
objectclass: organizationalUnit
ou: people
dn: uid=jdoe,ou=people,dc=example,dc=openidentityplatform,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: John Doe
sn: John
uid: jdoe
""";
InputStream inputStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
embeddedOpenDJ.importData(inputStream);
return embeddedOpenDJ;
}
If necessary, you can import data from any InputStream, such as a file reading stream.
Examination
To check functionality, you can use the library spring-ldap-core
Add dependencies to the project to run tests
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
<scope>test</scope>
</dependency>
Add compatibility options to maven-surefire-plugin
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${jvm.compatibility.args}</argLine>
</configuration>
</plugin>
And let's write a simple test that will launch a Spring Boot application with built-in OpenDJ, authenticate and look for the imported record:
@SpringBootTest
class OpenDJEmbeddedApplicationTest {
@Test
public void test() {
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl("ldap://localhost:1389");
contextSource.setBase("dc=example,dc=openidentityplatform,dc=org");
contextSource.setUserDn("cn=Directory Manager");
contextSource.setPassword("passw0rd");
contextSource.setPooled(true);
contextSource.afterPropertiesSet();
LdapTemplate template = new LdapTemplate(contextSource);
Object user = template.lookup("uid=jdoe,ou=people");
assertNotNull(user);
}
}