Spring LDAP 概述

Spring Security
Remote
0
12:42 AM · Nov 30 ,2025

1. 概述

LDAP 目錄服務器是優化後的分層數據存儲。通常,它們用於存儲用於用户身份驗證和授權的用户相關信息。

在本文中,我們將探索 Spring LDAP API 以進行用户身份驗證和搜索,以及在目錄服務器中創建和修改用户。相同的 API 組可用於管理 LDAP 中的任何其他類型的條目。

2. Maven 依賴項

讓我們首先添加所需的 Maven 依賴項:

<dependency>
    <groupId>org.springframework.ldap</groupId>
    <artifactId>spring-ldap-core</artifactId>
    <version>3.1.2</version>
</dependency>

此依賴項的最新版本可以在 spring-ldap-core 找到。

3. 數據準備

為了本文的目的,首先創建以下 LDAP 條目:

ou=users,dc=example,dc=com (objectClass=organizationalUnit)

在節點下,我們將創建新的用户、修改現有用户、驗證現有用户以及搜索信息。

4. Spring LDAP APIs

4.1. ContextSource & LdapTemplate Bean Definition

ContextSource is used for creating the LdapTemplate. We will see the use of ContextSource during user authentication in the next section:

@Bean
public LdapContextSource contextSource() {
    LdapContextSource contextSource = new LdapContextSource();
    
    contextSource.setUrl(env.getRequiredProperty("ldap.urls"));
    contextSource.setBase(
      env.getRequiredProperty("ldap.partitionSuffix"));
    contextSource.setUserDn(
      env.getRequiredProperty("ldap.principal"));
    contextSource.setPassword(
      env.getRequiredProperty("ldap.password"));
    
    return contextSource;
}

LdapTemplate is used for creation and modification of LDAP entries:

@Bean
public LdapTemplate ldapTemplate() {
    return new LdapTemplate(contextSource());
}

4.2. Using Spring Boot

When we are working on a Spring Boot project, we can use Spring Boot Starter Data Ldap dependency that will automatically instrument LdapContextSourceand LdapTemplatefor 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.urls=ldap://localhost:18889
spring.ldap.base=dc=example,dc=com
spring.ldap.username=uid=admin,ou=system
spring.ldap.password=secret

Then we are all set to inject the autoconfigured LdapTemplate into the required service class.

@Autowired
private LdapTemplate ldapTemplate;

4.3. User Authentication

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

public void authenticate(String username, String password) {
    contextSource
      .getContext(
        "cn=" + 
         username + 
         ",ou=users," + 
         env.getRequiredProperty("ldap.partitionSuffix"), password);
}

4.4. User Creation

Next, let’s create a new user and store an SHA hash of the password in LDAP.

At the time of authentication, the LDAP server generates the SHA hash of the supplied password and compares it to the stored one:

public void create(String username, String password) {
    Name dn = LdapNameBuilder
      .newInstance()
      .add("ou", "users")
      .add("cn", username)
      .build();
    DirContextAdapter context = new DirContextAdapter(dn);

    context.setAttributeValues(
      "objectclass", 
      new String[] 
        { "top", 
          "person", 
          "organizationalPerson", 
          "inetOrgPerson" });
    context.setAttributeValue("cn", username);
    context.setAttributeValue("sn", username);
    context.setAttributeValue("userPassword", digestSHA(password));

    ldapTemplate.bind(context);
}

digestSHA() is a custom method which returns the Base64 encoded string of the SHA hash of the supplied password.

Finally, thebind() method of LdapTemplate is used to create an entry in the LDAP server.

4.5. User Modification

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

public void modify(String username, String password) {
    Name dn = LdapNameBuilder.newInstance()
      .add("ou", "users")
      .add("cn", username)
      .build();
    DirContextOperations context 
      = ldapTemplate.lookupContext(dn);

    context.setAttributeValues
      ("objectclass", 
          new String[] 
            { "top", 
              "person", 
              "organizationalPerson", 
              "inetOrgPerson" });
    context.setAttributeValue("cn", username);
    context.setAttributeValue("sn", username);
    context.setAttributeValue("userPassword", 
      digestSHA(password));

    ldapTemplate.modifyAttributes(context);
}

ThelookupContext() method is used to find the supplied user.

4.6. User Search

We can search for existing users using search filters:

public List<String> search(String username) {
    return ldapTemplate
      .search(
        "ou=users", 
        "cn=" + username, 
        (AttributesMapper<String>) attrs -> (String) attrs.get("cn").get());
}

TheAttributesMapper is used to get the desired attribute value from the entries found. Internally, Spring LdapTemplate invokes the AttributesMapper for all the entries found and creates a list of the attribute values.

5. 測試

spring-ldap-test 提供了一個基於 ApacheDS 1.5.5 的嵌入式 LDAP 服務器。為了設置嵌入式 LDAP 服務器用於測試,我們需要配置以下 Spring Bean:

@Bean
public TestContextSourceFactoryBean testContextSource() {
    TestContextSourceFactoryBean contextSource 
      = new TestContextSourceFactoryBean();
    
    contextSource.setDefaultPartitionName(
      env.getRequiredProperty("ldap.partition"));
    contextSource.setDefaultPartitionSuffix(
      env.getRequiredProperty("ldap.partitionSuffix"));
    contextSource.setPrincipal(
      env.getRequiredProperty("ldap.principal"));
    contextSource.setPassword(
      env.getRequiredProperty("ldap.password"));
    contextSource.setLdifFile(
      resourceLoader.getResource(
        env.getRequiredProperty("ldap.ldiffile")));
    contextSource.setPort(
      Integer.valueOf(
        env.getRequiredProperty("ldap.port")));
    return contextSource;
}

讓我們使用 JUnit 測試我們的用户搜索方法:

@Test
public void 
  givenLdapClient_whenCorrectSearchFilter_thenEntriesReturned() {
    List<String> users = ldapClient
      .search(SEARCH_STRING);
 
    assertThat(users, Matchers.containsInAnyOrder(USER2, USER3));
}

6. 結論

在本文中,我們介紹了 Spring LDAP API 及其在 LDAP 服務器上進行用户身份驗證、用户搜索、用户創建和修改的簡單方法。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.