知識庫 / Spring / Spring Security RSS 訂閱

Spring LDAP 概述

Spring Security
HongKong
6
02:39 PM · Dec 06 ,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>

此依賴項的最新版本可以在 https://mvnrepository.com/artifact/org.springframework.ldap/spring-ldap-core 找到。

3. 數據準備

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

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

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

4. Spring LDAP APIs

Spring LDAP APIs 提供了一種方便的方式來使用各種 LDAP 目錄服務,例如 Active Directory、OpenLDAP 和其他基於 LDAP 的目錄。它允許你在 Spring 應用程序中使用 LDAP 進行身份驗證、用户管理和數據訪問。

主要功能:

  • 與 LDAP 目錄的連接: 提供與各種 LDAP 目錄的連接,支持多種 LDAP 協議(如 LDAPv3)。
  • 對象模型: 提供了一個基於 Java 的對象模型,用於表示 LDAP 目錄中的對象,例如用户、組和屬性。
  • 查詢和搜索: 支持使用 LDAP 查詢語言進行搜索和過濾。
  • 操作: 提供操作 LDAP 目錄的 API,例如添加、修改、刪除對象。
  • 與 Spring 框架的集成: 與 Spring 的其他模塊(如 Spring Security)無縫集成,方便在 Spring 應用程序中使用 LDAP。

示例代碼:

// Java 代碼示例 - 檢索用户
import org.springframework.ldap.core.support.DefaultLdapConnectionFactory;
import org.springframework.ldap.core.NamedNodeDefinition;
import org.springframework.ldap.core.support.SimpleLdapConnectionFactory;

// ...

SimpleLdapConnectionFactory connectionFactory = new SimpleLdapConnectionFactory("ldap://localhost:1389"); // 替換為你的 LDAP 服務器地址

// 檢索名為 "user1" 的用户
User user = connectionFactory.getConnection().lookup("cn=user1,dc=example,dc=com");

if (user != null) {
    System.out.println("User found: " + user.getName());
} else {
    System.out.println("User not found.");
}

4.1. <em>ContextSource</em> &amp; <em>LdapTemplate</em> Bean 定義

<em>ContextSource</em> 用於創建LdapTemplate。我們在下一部分將看到ContextSource在用户身份驗證中的使用:

@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 用於 LDAP 條目的創建和修改。

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

4.2. 使用 Spring Boot

當我們在 Spring Boot 項目中工作時,可以使用 Spring Boot Starter Data Ldap 依賴項,它將自動為 LdapContextSourceLdapTemplate 進行儀器化。

為了啓用自動配置,我們需要確保我們已將 spring-boot-starter-data-ldap Starter 或 spring-ldap-core 定義為 pom.xml 中的依賴項:

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

要連接到 LDAP,我們需要在應用程序的 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

然後,我們將所有配置好的 LdapTemplate 注入到所需的 Service 類中。

@Autowired
private LdapTemplate ldapTemplate;

4.3. 用户身份驗證

現在,讓我們實現一段簡單的邏輯來驗證現有用户:

public void authenticate(String username, String password) {
    contextSource
      .getContext(
        "cn=" + 
         username + 
         ",ou=users," + 
         env.getRequiredProperty("ldap.partitionSuffix"), password);
}
<h3><strong>4.4. 用户創建</strong></h3>
<p>接下來,我們將創建一個新用户並將其密碼的 SHA 哈希值存儲在 LDAP 中。</p>
<p>在身份驗證過程中,LDAP 服務器會生成提供的密碼的 SHA 哈希值,並將其與存儲的哈希值進行比較。</p>
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() 是一個自定義方法,它返回提供的密碼的 SHA 哈希值的 Base64 編碼字符串。

最後,LdapTemplatebind() 方法用於在 LDAP 服務器上創建條目。

4.5. 用户修改

我們可以使用以下方法修改現有用户或條目:

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);
}

lookupContext()方法用於查找提供的用户。

4.6. 用户搜索

我們可以使用搜索過濾器搜索現有用户:

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

AttributesMapper 用於從找到的條目中獲取所需的屬性值。內部而言,Spring 的 LdapTemplate 會調用 AttributesMapper 對所有找到的條目進行操作,並創建一個包含屬性值的列表。

5. 測試

<em>spring-ldap-test</em> 提供了一個基於 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.