Spring Boot集成Ldap快速入门Demo

1.Ldap介绍

LDAP,Lightweight Directory Access Protocol,轻量级目录访问协议.

  1. LDAP是一种特殊的服务器,可以存储数据

  2. 数据的存储是目录形式的,或者可以理解为树状结构(一层套一层)

  3. 一般存储关于用户、用户认证信息、组、用户成员,通常用于用户认证与授权

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=orgpassword:admin

init data

dn: ou=people,dc=exapmple,dc=orgobjectClass: topobjectClass: organizationalUnitou: 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)@SpringBootTestpublic 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.引用参考

  • http://www.liuhaihua.cn/archives/710513.html

  • https://spring.io/guides/gs/authenticating-ldap/

  • https://blog.csdn.net/Zhangmaoyang/article/details/123113262

相关推荐

  • 「超星未来」完成数亿元Pre-B轮融资,加码边缘侧大模型推理芯片
  • AI预测所有生命分子!谷歌AlphaFold 3模型登Nature,免费开放节省上亿年研究时间
  • 恭喜,77所高校入选 “101计划”!!!
  • 【Python】10个杀手级的Python自动化脚本!
  • 选导师选了个大牛,什么都不管,估计要被放养三年。。。
  • 前端权限开发——设计到实践(保姆级)
  • 3 个超酷的 Node.js 新功能!
  • 写出好代码的底层逻辑!
  • 时间序列概率预测的共形预测
  • SIGIR2024 | UniSAR: 搜索与推荐统一用户转换行为建模
  • 综述170篇「自监督学习」推荐算法,港大发布SSL4Rec:代码、资料库全面开源!
  • 清华首个AI医院小镇来了!AI医生自进化击败人类专家,数天诊完1万名患者
  • ICLR被曝巨大黑幕,评审和作者竟私下勾结?49.9%论文疑有AI审稿
  • AlphaFold 3一夜预测地球所有生物分子,谷歌DeepMind颠覆生物学登Nature头版!
  • 7262 篇提交,ICLR 2024 爆火,两篇国内论文获杰出论文提名
  • 多模态,杀疯了!
  • 本地运行大模型,复刻ChatGPT聊天界面
  • Signal 也许真的能杀死 Virtual DOM !!!
  • 前端面试这样准备,拿45k真的不难。。。
  • 字节面试官:45k+前端面试都问这些!