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: openldapimage: osixia/openldap:latestports:- "8389:389"- "8636:636"volumes:- ~/ldap/backup:/data/backup- ~/ldap/data:/var/lib/openldap- ~/ldap/config:/etc/openldap/slapd.d- ~/ldap/certs:/assets/slapd/certscommand: [--copy-service,  --loglevel, debug]phpldapadmin:container_name: phpldapadminimage: osixia/phpldapadmin:latestports:- "8080:80"environment:- PHPLDAPADMIN_HTTPS="false"- PHPLDAPADMIN_LDAP_HOSTS=openldaplinks:- openldapdepends_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

58

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 configurationldap:urls: ldap://127.0.0.1:8389base: dc=example,dc=orgusername: cn=admin,${spring.ldap.base}password: adminserver: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*/@Idprivate 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 {@Autowiredprivate LdapTemplate ldapTemplate;/*** add person*/@Testpublic void addPerson() {Person person = new Person();person.setUid("uid:14");person.setSuerName("LISI");person.setCommonName("lisi");person.setUserPassword("123456");ldapTemplate.create(person);}/*** filter search*/@Testpublic 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() {@Overridepublic 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*/@Testpublic 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() {@Overridepublic 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);}
}

运行单元测试类,查看数据,可以看到新增一个人

80

5.引用参考

  • Spring Boot集成Ldap快速入门Demo | Harries Blog™
  • Getting Started | Authenticating a User with LDAP
  • Docker安装LDAP并集成Springboot测试LDAP_ladp dockers-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/323255.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

吴恩达机器学习笔记:第 9 周-17大规模机器学习(Large Scale Machine Learning)17.3-17.4

目录 第 9 周 17、 大规模机器学习(Large Scale Machine Learning)17.3 小批量梯度下降17.4 随机梯度下降收敛 第 9 周 17、 大规模机器学习(Large Scale Machine Learning) 17.3 小批量梯度下降 小批量梯度下降算法是介于批量梯度下降算法和随机梯度下降算法之间的算法&…

基于Springboot的线上教学平台

基于SpringbootVue的线上教学平台设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页 学习资料 交流论坛 试卷列表 公告信息 后台登录 后台首页 学员管理 资料类型…

Junit 测试中如何对异常进行断言

本文对在 Junit 测试中如何对异常进行断言的几种方法进行说明。 使用 Junit 5 如果你使用 Junit 5 的话&#xff0c;你可以直接使用 assertThrows 方法来对异常进行断言。 代码如下&#xff1a; Exception exception assertThrows(NumberFormatException.class, () -> {n…

Universal Thresholdizer:将多种密码学原语门限化

参考文献&#xff1a; [LS90] Lapidot D, Shamir A. Publicly verifiable non-interactive zero-knowledge proofs[C]//Advances in Cryptology-CRYPTO’90: Proceedings 10. Springer Berlin Heidelberg, 1991: 353-365.[Shoup00] Shoup V. Practical threshold signatures[C…

七、 数据出境安全评估申报需要多长时间?

《评估申报指南&#xff08;第二版&#xff09;》未区分数据处理者进行数据出境安全评估线上申报和线下申报整体所需时间。一般情况下&#xff0c;数据出境安全评估的申报时长周期如图所示&#xff1a; 根据《评估申报指南&#xff08;第二版&#xff09;》第二条的规定&#…

Spirng-IOC零碎知识点

Spirng IOC 依赖注入 根据名称注入 <?xml version"1.0" encoding"UTF-8"?> <beansxmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:util"http://w…

引入RabbitMQ

前置条件 docker 安装 mq docker run \-e RABBITMQ_DEFAULT_USERdudu \-e RABBITMQ_DEFAULT_PASS123456 \-v mq-plugins:/plugins \--name mq \--hostname mq \-p 15672:15672 \-p 5672:5672 \--network hmall \-d \rabbitmq:3.8-management可能会出现&#xff1a;docker: Er…

【深度学习】【Lora训练0】StabelDiffusion,Lora训练,kohya_ss训练

文章目录 环境数据自动标注kohya_ss BLIP2kohya_ss WD14 后续 资源&#xff1a; &#xff08;1&#xff09;训练ui kohya_ss&#xff1a; https://github.com/bmaltais/kohya_ss &#xff08;2&#xff09;kohya_ss 的docker 其他docker https://github.com/ashleykleynhans…

GraphGPT——图结构数据的新语言模型

在人工智能的浪潮中&#xff0c;图神经网络&#xff08;GNNs&#xff09;已经成为理解和分析图结构数据的强大工具。然而&#xff0c;GNNs在面对未标记数据时&#xff0c;其泛化能力往往受限。为了突破这一局限&#xff0c;研究者们提出了GraphGPT&#xff0c;这是一种为大语言…

AcWing 161:电话列表 ← 字典树(Trie 树)之前缀匹配

【题目来源】https://www.acwing.com/problem/content/163/【题目描述】 给出一个电话列表&#xff0c;如果列表中存在其中一个号码是另一个号码的前缀这一情况&#xff0c;那么就称这个电话列表是不兼容的。 假设电话列表如下&#xff1a;Emergency 911 Alice 97625999 Bob …

2022 亚马逊云科技中国峰会,对话开发者论坛

目录 前言 最近整理资料发现还有一些前 2 年的内容没发出来&#xff0c;故补发记录&#xff0c;每年都有新的感悟。 开发者论坛 1. 你认为什么是开发者社区&#xff0c;如何定义一个成功的开发者社区&#xff1f; 我认为可以把开发者社区看成一个 “产品” 来对待&#xff…

ESP8266-01s刷入固件报SP8266 Chip efuse check error esp_check_mac_and_efuse

一、遇到的问题 使用ESP8266 固件烧录工具flash_download_tools_v3.6.8 烧录固件报错&#xff1a; 二、解决方法 使用espressif推出发基于python的底层烧写工具&#xff1a;esptool 安装方法&#xff1a;详见https://docs.espressif.com/projects/esptool/en/latest/esp32/ …

电脑中的两个固态硬盘比一个好,想知道为什么吗

你当前的电脑很有可能有一个NVME SSD作为主驱动器&#xff0c;但可能至少还有一个插槽可以放另一个SSD&#xff0c;而且这样做可能是个好主意。 两个SSD可以提高性能 如果你有两个固态硬盘&#xff0c;你可以从中获得比有一个更好的性能。一种方法是使用RAID 0将两个驱动器组…

《ESP8266通信指南》14-连接WIFI(基于Lua)

往期 《ESP8266通信指南》13-Lua 简单入门&#xff08;打印数据&#xff09;-CSDN博客 《ESP8266通信指南》12-Lua 固件烧录-CSDN博客 《ESP8266通信指南》11-Lua开发环境配置-CSDN博客 《ESP8266通信指南》10-MQTT通信&#xff08;Arduino开发&#xff09;-CSDN博客 《ES…

eNSP-浮动静态路由配置

ip route-static 192.168.1.0 24 192.168.3.2 preference 60 #设置路由 目标网络地址 和 下一跳地址 preference值越大 优先级越低 一、搭建拓扑结构 二、主机配置 pc1 pc2 三、配置路由器 1.AR1路由器配置 <Huawei>sys #进入系统视图 [Huawei]int g0/0/0 #进入接…

喜报|知从科技荣获“2023年度浦东新区创新创业奖”

4月11日&#xff0c;由上海市浦东新区人民政府举办的“2024年浦东新区经济突出贡献企业表彰活动”在上海国际会议中心隆重举行。知从科技凭借过去一年在行业内卓越的技术创新实力及对浦东新区发展作出的杰出贡献&#xff0c;入选创新创业20强企业&#xff0c;荣获“2023年度浦东…

C++类和对象(4)

目录 1.初始化列表 2.单参数里面的隐式类型转换 3.多参数的隐式类型转换 4.匿名对象 1.初始化列表 &#xff08;1&#xff09;首先看一下初始化列表具体是什么&#xff1f; 这个就是初始化列表的具体形式&#xff0c;对&#xff0c;你没有看错&#xff0c;这个初始化列表里…

Hotcoin Research | 模块化将是大势所趋:拆解模块化区块链的现状和未来

关于模块化区块链叙事的讨论源于Celestia和其代币TIA的亮眼表现。实际上&#xff0c;模块化是未来区块链设计的主要发展方向和大势所趋。模块化区块链就像乐高积木一样&#xff0c;将区块链系统拆分为可重用的模块&#xff0c;通过定制组合可实现不同功能的区块链网络。这种灵活…

锂电池恒流恒压CCCV充电模型MATLAB仿真

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; CCCV简介 CCCV充电过程是恒流充电&#xff08;CC&#xff09;和恒压充电&#xff08;CV&#xff09;的结合。在CC阶段对电池施加恒定电流&#xff0c;以获得更快的充电速度&#xff0c;此时电池电压持续升高…

C++基础——输入输出(文件)

一、标准输入输出流 C 的输入输出是程序与用户或外部设备&#xff08;如文件、网络等&#xff09;之间交换信息的过程。 C 提供了丰富的标准库来支持这种交互&#xff0c;主要通过流的概念来实现。 流&#xff1a;抽象概念&#xff0c;表示一连串的数据&#xff08;字节或字…