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
@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;
}
@Bean
public LdapTemplate ldapTemplate() {
return new LdapTemplate(contextSource());
}
4.2. Using Spring Boot
To enable autoconfiguration, we need to ensure that we have the
<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
@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);
}
Finally, the
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);
}
The
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());
}
The
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 服務器上進行用户身份驗證、用户搜索、用户創建和修改的簡單方法。