Spring Boot integrated Ldap Quick start Demo

HBLOG
4 min readMay 7, 2024

--

1.Ldap introduce

LDAP,Lightweight Directory Access Protocol, Lightweight Directory Access Protocol.

  1. LDAP is a special server that can store data
  2. Data is stored in the form of a directory, or it can be understood as a tree structure (layer within layer)
  3. Generally stores information about users, user authentication information, groups, and user members, and is usually used for user authentication and authorization.

LDAP Abbreviated correspondence

  • o:organization
  • ou:organization unit
  • c:countryName
  • dc:domainComponent
  • sn:surname
  • cn:common name

2.Environment setup

docker-compose-ldap.yaml

version: '3'
services:
openldap:
container_name: openldap
image: osixia/openldap:latest
ports:
- "8389:389"
- "8636:636"
volumes:
- ~/ldap/backup:/data/backup
- ~/ldap/data:/var/lib/openldap
- ~/ldap/config:/etc/openldap/slapd.d
- ~/ldap/certs:/assets/slapd/certs
command: [--copy-service, --loglevel, debug]
phpldapadmin:
container_name: phpldapadmin
image: osixia/phpldapadmin:latest
ports:
- "8080:80"
environment:
- PHPLDAPADMIN_HTTPS="false"
- PHPLDAPADMIN_LDAP_HOSTS=openldap
links:
- openldap
depends_on:
- openldap

ldap setup

docker-compose -f docker-compose-ldap.yml -p ldap up -d

open http://localhost:8080/

default account

username:cn=admin,dc=example,dc=org
password:admin

init data

dn: ou=people,dc=exapmple,dc=org
objectClass: top
objectClass: organizationalUnit
ou: people

3.code engineering

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot-demo</artifactId>
<groupId>com.et</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ldap</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--ldap-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-ldap</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>

application.yaml

spring:
application:
name: spring-demo-ldap
# ldap configuration
ldap:
urls: ldap://127.0.0.1:8389
base: dc=example,dc=org
username: cn=admin,${spring.ldap.base}
password: admin
server:
port: 8088

Person.java

package com.et.ldap.entity;

import lombok.Data;
import org.springframework.ldap.odm.annotations.Attribute;
import org.springframework.ldap.odm.annotations.DnAttribute;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.annotations.Id;

import javax.naming.Name;
import java.io.Serializable;
@Data
@Entry(base = "ou=people", objectClasses="inetOrgPerson")
public class Person implements Serializable {

private static final long serialVersionUID = -337113594734127702L;

/**
*neccesary
*/
@Id
private Name id;

@DnAttribute(value = "uid", index = 3)
private String uid;

@Attribute(name = "cn")
private String commonName;

@Attribute(name = "sn")
private String suerName;

private String userPassword;

}

The above are just some key codes. For all codes, please see the code repository below.

code repository

4.Test

package com.et.ldap;
import com.et.ldap.entity.Person;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.ldap.NamingException;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import java.util.List;
import static org.springframework.ldap.query.LdapQueryBuilder.query;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
private LdapTemplate ldapTemplate;
/**
* add person
*/
@Test
public void addPerson() {
Person person = new Person();
person.setUid("uid:14");
person.setSuerName("LISI");
person.setCommonName("lisi");
person.setUserPassword("123456");
ldapTemplate.create(person);
}
/**
* filter search
*/
@Test
public void filterSearch() {
// Get the domain list. If you want to get a certain domain, the filter can be written like this: (&(objectclass=dcObject)&(dc=example))
// String filter = "(&(objectclass=dcObject))";
// Get the list of organizations. If you want to get a specific organization, the filter can be written like this: (&(objectclass=organizationalUnit)&(ou=people)
// String filter = "(&(objectclass=organizationalUnit))";
//Get the people list. If you want to get a certain person, the filter can be written like this: (&(objectclass=inetOrgPerson)&(uid=uid:13))
String filter = "(&(objectclass=inetOrgPerson))";
List<Person> list = ldapTemplate.search("", filter, new AttributesMapper() {
@Override
public Object mapFromAttributes(Attributes attributes) throws NamingException, javax.naming.NamingException {
NamingEnumeration<? extends Attribute> att = attributes.getAll();
while (att.hasMore()) {
Attribute a = att.next();
System.out.println(a.getID() + "=" + a.get());
}
Person p = new Person();
Attribute a = attributes.get("cn");
if (a != null) p.setCommonName((String) a.get());
a = attributes.get("uid");
if (a != null) p.setUid((String) a.get());
a = attributes.get("sn");
if (a != null) p.setSuerName((String) a.get());
a = attributes.get("userPassword");
if (a != null) p.setUserPassword(a.get().toString());
return p;
}
});
list.stream().forEach(System.out::println);
}
/**
* query search
*/
@Test
public void querySearch() {
// You can also use filter query method, filter is (&(objectClass=user)(!(objectClass=computer))
List<Person> personList = ldapTemplate.search(query()
.where("objectClass").is("inetOrgPerson")
.and("uid").is("uid:14"),
new AttributesMapper() {
@Override
public Person mapFromAttributes(Attributes attributes) throws NamingException, javax.naming.NamingException {
//If you don't know what attributes are in ldap, you can print them in the following way
// NamingEnumeration<? extends Attribute> att = attr.getAll();
//while (att.hasMore()) {
// Attribute a = att.next();
// System.out.println(a.getID());
//}
Person p = new Person();
Attribute a = attributes.get("cn");
if (a != null) p.setCommonName((String) a.get());
a = attributes.get("uid");
if (a != null) p.setUid((String) a.get());
a = attributes.get("sn");
if (a != null) p.setSuerName((String) a.get());
a = attributes.get("userPassword");
if (a != null) p.setUserPassword(a.get().toString());
return p;
}
});
personList.stream().forEach(System.out::println);
}
}

Run the unit test class and view the data. You can see that a new person has been added.

5.References

--

--