SoFunction
Updated on 2025-04-14

Example of using Spring LDAP directory service

introduction

In an enterprise environment, the Lightweight Directory Access Protocol (LDAP) plays an important role as a standard protocol for centralized user management and authentication. LDAP servers store organizational structured data, including user, organization, and permission information. Spring LDAP is a subproject of the Spring family, which simplifies the interaction process between Java applications and LDAP servers. This article will explore the core concepts of Spring LDAP, how to use LdapTemplate, and how to perform common LDAP operations to help developers effectively integrate LDAP into Spring applications.

1. Spring LDAP basics

Spring LDAP provides an abstraction layer that enables developers to interact with LDAP in a Spring-style way, avoiding the complexity of directly dealing with the underlying JNDI API. It follows a template pattern similar to Spring JDBC, providing a concise interface to perform LDAP operations through LdapTemplate.

To start using Spring LDAP, you need to add relevant dependencies first. For Maven projects, you can add:

<dependency>
    <groupId></groupId>
    <artifactId>spring-ldap-core</artifactId>
    <version>2.4.1</version>
</dependency>

<!-- integratedSpring Boot -->
<dependency>
    <groupId></groupId>
    <artifactId>spring-boot-starter-data-ldap</artifactId>
</dependency>

In Spring Boot project, configuring LDAP connection information can be done in or:

# LDAP server configuration=ldap://:389
=dc=example,dc=com
=cn=admin,dc=example,dc=com
=admin_password

2. Detailed explanation of LdapTemplate

LdapTemplate is the core class of Spring LDAP. It encapsulates the complexity of LDAP operations and provides a simple set of APIs. In Spring Boot environment, LdapTemplate will be automatically configured and can be injected directly into use:

import ;
import ;
import ;

@Service
public class LdapService {
    
    private final LdapTemplate ldapTemplate;
    
    @Autowired
    public LdapService(LdapTemplate ldapTemplate) {
         = ldapTemplate;
    }
    
    // Use ldapTemplate to perform LDAP operations}

If you do not use Spring Boot, you need to configure LdapTemplate manually:

import ;
import ;
import ;
import ;

@Configuration
public class LdapConfig {
    
    @Bean
    public LdapContextSource contextSource() {
        LdapContextSource contextSource = new LdapContextSource();
        ("ldap://:389");
        ("dc=example,dc=com");
        ("cn=admin,dc=example,dc=com");
        ("admin_password");
        return contextSource;
    }
    
    @Bean
    public LdapTemplate ldapTemplate() {
        return new LdapTemplate(contextSource());
    }
}

LdapTemplate provides a variety of methods to perform LDAP operations, including search, binding, modification and deletion. It also supports callback methods, allowing developers to customize result processing logic.

3. LDAP object mapping

Spring LDAP provides object-directory mapping (ODM) functionality, similar to ORM (Object-Relational Mapping), which can map LDAP entries to Java objects. By using annotations, it is easy to convert between LDAP entries and Java classes:

import .*;
import ;

@Entry(base = "ou=people", objectClasses = {"person", "inetOrgPerson"})
public class User {
    
    @Id
    private Name id;
    
    @Attribute(name = "cn")
    private String commonName;
    
    @Attribute(name = "sn")
    private String surname;
    
    @Attribute(name = "mail")
    private String email;
    
    @Attribute(name = "telephoneNumber")
    private String phoneNumber;
    
    // Getters and setters
    public Name getId() {
        return id;
    }
    
    public void setId(Name id) {
         = id;
    }
    
    public String getCommonName() {
        return commonName;
    }
    
    public void setCommonName(String commonName) {
         = commonName;
    }
    
    // Other getters and setters}

In the above example, the @Entry annotation defines the basic information of the LDAP entry, the @Id annotation marks the unique identifier of the entry, and the @Attribute annotation maps the Java attribute to the LDAP attribute.

4. Basic LDAP operation

4.1 Query operation

Using LdapTemplate for querying is the most common operation. Various methods can be used to perform searches:

import ;
import ;
import ;
import ;
import ;

import ;
import ;

@Service
public class UserService {
    
    private final LdapTemplate ldapTemplate;
    
    public UserService(LdapTemplate ldapTemplate) {
         = ldapTemplate;
    }
    
    public List<String> getAllUsernames() {
        return (
            "ou=people", // Search basics            "(objectclass=person)", // Search filter            (AttributesMapper<String>) attrs -> (String) ("cn").get() // Attribute mapping        );
    }
    
    public List<User> findUserByEmail(String email) {
        Filter filter = new EqualsFilter("mail", email);
        return (
            "ou=people",
            (),
            (AttributesMapper<User>) attrs -> {
                User user = new User();
                ((String) ("cn").get());
                ((String) ("sn").get());
                ((String) ("mail").get());
                return user;
            }
        );
    }
}

Using the ODM function, you can directly map search results to Java objects:

import ;
import ;
import ;
import ;

@Service
public class UserService {
    
    private final LdapTemplate ldapTemplate;
    
    public UserService(LdapTemplate ldapTemplate) {
         = ldapTemplate;
    }
    
    public List<User> findUserByEmail(String email) {
        LdapQuery query = ()
            .base("ou=people")
            .where("objectclass").is("person")
            .and("mail").is(email);
        
        return (query, );
    }
}

4.2 Add operations

Adding a new entry can be done by creating the object directly and then using the create method of LdapTemplate:

import ;
import ;
import ;

import ;

@Service
public class UserService {
    
    private final LdapTemplate ldapTemplate;
    
    public UserService(LdapTemplate ldapTemplate) {
         = ldapTemplate;
    }
    
    public void createUser(String username, String surname, String email) {
        Name dn = ()
            .add("ou", "people")
            .add("cn", username)
            .build();
        
        DirContextAdapter context = new DirContextAdapter(dn);
        
        ("objectclass", new String[]{"top", "person", "inetOrgPerson"});
        ("cn", username);
        ("sn", surname);
        ("mail", email);
        
        (context);
    }
}

Using the ODM function, it is easier to create and save objects:

@Service
public class UserService {
    
    private final LdapTemplate ldapTemplate;
    
    public UserService(LdapTemplate ldapTemplate) {
         = ldapTemplate;
    }
    
    public void createUser(String username, String surname, String email) {
        User user = new User();
        (()
            .add("cn", username)
            .build());
        (username);
        (surname);
        (email);
        
        (user);
    }
}

4.3 Modify operations

Modifying an existing entry can be done by looking for an entry, modifying properties, and then updating:

@Service
public class UserService {
    
    private final LdapTemplate ldapTemplate;
    
    public UserService(LdapTemplate ldapTemplate) {
         = ldapTemplate;
    }
    
    public void updateUserEmail(String username, String newEmail) {
        Name dn = ()
            .add("ou", "people")
            .add("cn", username)
            .build();
        
        DirContextOperations context = (dn);
        ("mail", newEmail);
        
        (context);
    }
}

Using ODM function:

@Service
public class UserService {
    
    private final LdapTemplate ldapTemplate;
    
    public UserService(LdapTemplate ldapTemplate) {
         = ldapTemplate;
    }
    
    public void updateUserEmail(String username, String newEmail) {
        LdapQuery query = ()
            .base("ou=people")
            .where("cn").is(username);
        
        User user = (query, );
        if (user != null) {
            (newEmail);
            (user);
        }
    }
}

4.4 Delete operation

The operation of deleting an entry is relatively simple:

@Service
public class UserService {
    
    private final LdapTemplate ldapTemplate;
    
    public UserService(LdapTemplate ldapTemplate) {
         = ldapTemplate;
    }
    
    public void deleteUser(String username) {
        Name dn = ()
            .add("ou", "people")
            .add("cn", username)
            .build();
        
        (dn);
    }
}

Using ODM function:

@Service
public class UserService {
    
    private final LdapTemplate ldapTemplate;
    
    public UserService(LdapTemplate ldapTemplate) {
         = ldapTemplate;
    }
    
    public void deleteUser(String username) {
        LdapQuery query = ()
            .base("ou=people")
            .where("cn").is(username);
        
        User user = (query, );
        if (user != null) {
            (user);
        }
    }
}

V. Certification and Authorization

Spring LDAP can be integrated with Spring Security to implement LDAP-based authentication and authorization:

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .ldapAuthentication()
            .userDnPatterns("cn={0},ou=people")
            .groupSearchBase("ou=groups")
            .contextSource()
            .url("ldap://:389/dc=example,dc=com")
            .and()
            .passwordCompare()
            .passwordAttribute("userPassword");
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER")
            .anyRequest().authenticated()
            .and()
            .formLogin();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        // Note: NoOpPasswordEncoder should not be used in production environment        return ();
    }
}

6. Advanced features and best practices

Spring LDAP provides advanced features such as paging queries, sorting, and connection pooling configurations, which are particularly important for handling large directory services:

// Configure the connection pool@Bean
public LdapContextSource contextSource() {
    LdapContextSource contextSource = new LdapContextSource();
    ("ldap://:389");
    ("dc=example,dc=com");
    ("cn=admin,dc=example,dc=com");
    ("admin_password");
    
    //Connection pool configuration    (true);
    
    return contextSource;
}

@Bean
public PoolingContextSource poolingContextSource(LdapContextSource contextSource) {
    DefaultTlsDirContextAuthenticationStrategy strategy = new DefaultTlsDirContextAuthenticationStrategy();
    ((hostname, session) -&gt; true);
    (strategy);
    
    PoolConfig poolConfig = new PoolConfig();
    (5);
    (20);
    (10);
    
    PoolingContextSource poolingContextSource = new PoolingContextSource();
    (contextSource);
    (poolConfig);
    
    return poolingContextSource;
}

// Example of pagination querypublic List&lt;User&gt; findUsersPaged(int pageSize, int pageNumber) {
    PagedResultsDirContextProcessor processor = new PagedResultsDirContextProcessor(pageSize);
    LdapQuery query = ()
        .base("ou=people")
        .where("objectclass").is("person");
    
    // Execute the first page query    List&lt;User&gt; users = new ArrayList&lt;&gt;();
    for (int i = 0; i &lt; pageNumber; i++) {
        users = (query, new PersonAttributesMapper(), processor);
        
        // If there are no more results or the requested page number has been reached, stop        if (!() || i == pageNumber - 1) {
            break;
        }
        
        // Set cookies to get the next page        ();
    }
    
    return users;
}

Summarize

Spring LDAP provides developers with a powerful and flexible framework that simplifies interaction with LDAP directory services. With LdapTemplate, developers can easily perform various LDAP operations without having to dig deep into the complexity of the underlying JNDI API. The object-directory mapping function makes the conversion of LDAP entries and Java objects simple and intuitive, improving the readability and maintainability of the code. Integration with Spring Security makes it easy to implement LDAP-based authentication and authorization. Spring LDAP is an ideal choice in enterprise applications, especially in scenarios where centralized user management is required.

This is the end of this article about the use examples of Spring LDAP directory service. For more related Spring LDAP directory service content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!