1.Ldap介绍
LDAP,Lightweight Directory Access Protocol,轻量级目录访问协议.
- LDAP是一种特殊的服务器,可以存储数据
- 数据的存储是目录形式的,或者可以理解为树状结构(一层套一层)
- 一般存储关于用户、用户认证信息、组、用户成员,通常用于用户认证与授权
LDAP简称对应
- o:organization(组织-公司)
- ou:organization unit(组织单元-部门)
- c:countryName(国家)
- dc:domainComponent(域名)
- sn:surname(姓氏)
- cn:common name(常用名称)
2.环境搭建
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.代码工程
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;
}
以上只是一些关键代码,所有代码请参见下面代码仓库
代码仓库
- https://github.com/Harries/springboot-demo
4.测试
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 {
//如果不知道ldap中有哪些属性,可以使用下面这种方式打印
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);
}
}
运行单元测试类,查看数据,可以看到新增一个人
5.引用参考
- Spring Boot集成Ldap快速入门Demo | Harries Blog™
- Getting Started | Authenticating a User with LDAP
- Docker安装LDAP并集成Springboot测试LDAP_ladp dockers-CSDN博客