1. Introduction

In this article, we’ll focus on Spring Data LDAP integration and configuration. For a step by step introduction to Spring LDAP, have a quick look at this article.

Also, you can find the overview of Spring Data JPA guide here.

2. Maven Dependency

Let’s begin by adding the required Maven dependencies:

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-ldap</artifactId>
    <version>3.1.5</version>
</dependency>

The latest versions can be found here for spring-data-ldap.

3. Domain Entry

Spring LDAP project provides an ability to map LDAP entries to Java objects by using Object-Directory Mapping (ODM).

Let’s define the entity which will be used to map LDAP directories which have already been configured in the Spring LDAP article.

@Entry(
  base = "ou=users", 
  objectClasses = { "person", "inetOrgPerson", "top" })
public class User {
    @Id
    private Name id;
    
    private @Attribute(name = "cn") String username;
    private @Attribute(name = "sn") String password;

    // standard getters/setters
}

@Entry is similar to @Entity (of JPA/ORM) which is used to specify which entity maps to directory root of the LDAP entries.

An Entry class must have @Id annotation declared on a field of type javax*.naming.Name* which represents entity DN. The @Attribute annotation is used to map object class fields to entity fields.

4. Spring Data Repository

Spring Data Repository is an abstraction which provides basic out-of-the-box ready to use implementation of data access layers for various persistence stores.

Spring Framework internally provides the implementation of CRUD operations for given class in the data repository. We can find the complete detail in Introduction to Spring Data JPA article.

Spring Data LDAP provides similar abstraction which provides the automatic implementation of Repository interfaces that include basic CRUD operation for LDAP directories.

Also, Spring Data Framework can create a custom query based on a method name.

Let’s define our repository interface which will be used to manage User Entry:

@Repository
public interface UserRepository extends LdapRepository<User> {
    User findByUsername(String username);
    User findByUsernameAndPassword(String username, String password);
    List<User> findByUsernameLikeIgnoreCase(String username);
}

As we can see, we have declared an interface by extending LdapRepository for entry User. Spring Data Framework will automatically provide basic CRUD method implementation such as find(), findAll(), save(), delete(), etc.

Also, we have declared a few custom methods. Spring Data Framework will provide the implementation by probing the method name with a strategy known as Query Builder Mechanism.

5. Configuration

We can configure Spring Data LDAP using Java-based @Configuration classes or an XML namespace. Let’s configure the repository using the Java-based approach:

@Configuration
@EnableLdapRepositories(basePackages = "com.baeldung.ldap.**")
public class AppConfig {
}

@EnableLdapRepositories hints Spring to scan the given package for interfaces marked as @Repository.

6. Using Spring Boot

When working on a Spring Boot project, we can use Spring Boot Starter Data Ldap dependency that will automatically instrument LdapContextSource and LdapTemplate for us. 

To enable autoconfiguration, we need to ensure that we have the spring-boot-starter-data-ldap Starter or spring-ldap-core defined as a dependency in our pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-ldap</artifactId>
</dependency>

To connect to LDAP, we need to provide the connection settings in the application.properties:

spring.ldap.url=ldap://localhost:18889
spring.ldap.base=dc=example,dc=com
spring.ldap.username=uid=admin,ou=system
spring.ldap.password=secret

More details about Spring Data LDAP autoconfiguration can be found in the official documentation. Spring Boot brings in LdapAutoConfiguration which takes care of instrumentation of LdapTemplate which can then be injected into the required service class:

@Autowired
private LdapTemplate ldapTemplate;

7. Business Logic

Let’s define our service class which will use the UserRepository to operate on LDAP directories:

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    // business methods
}

Now, we will explore one action at a time and see how easily we can perform these action using Spring Data Repository

7.1. User Authentication

Let’s now implement a simple piece of logic to authenticate an existing user:

public Boolean authenticate(String u, String p) {
    return userRepository.findByUsernameAndPassword(u, p) != null;
}

7.2. User Creation

Next, let’s create a new user and store a password’s hash:

public void create(String username, String password) {
    User newUser = new User(username,digestSHA(password));
    newUser.setId(LdapUtils.emptyLdapName());
    userRepository.save(newUser);
}

7.3. User Modification

We can modify an existing user or entry with the following method:

public void modify(String u, String p) {
    User user = userRepository.findByUsername(u);
    user.setPassword(p);
    userRepository.save(user);
}

We can search for existing users using a custom method:

public List<String> search(String u) {
    List<User> userList = userRepository
      .findByUsernameLikeIgnoreCase(u);
    
    if (userList == null) {
        return Collections.emptyList();
    }

    return userList.stream()
      .map(User::getUsername)
      .collect(Collectors.toList());  
}

8. Example in Action

Finally, we can quickly test a simple authentication scenario:

@Test
public void givenLdapClient_whenCorrectCredentials_thenSuccessfulLogin() {
    Boolean isValid = userService.authenticate(USER3, USER3_PWD);
 
    assertEquals(true, isValid);
}

9. Conclusion

This quick tutorial demonstrated the basics of Spring LDAP repository configuration and CRUD operation.

The example used in this article can be found over on GitHub.