Spring Boot集成Ldap快速入门Demo

news2024/11/16 16:01:30

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=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 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);
    }
}

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

80

5.引用参考

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多规格产品应该如何设置呢?

今天一用户从供应商手中拿到产品价目表&#xff0c;但是设置起来蒙圈了&#xff0c;接下来我们就一起设置一下吧&#xff5e; 一、产品价格表 我们通过供应商手中拿到产品价目表是这个样子的&#xff1a; 我们可以看到此产品的销售客价根据不同地区导致的价格不同&#xff0…

环绕数字化学校,打造四个体系

近年来&#xff0c;各地学校活跃顺应“互联网教育”发展大势&#xff0c;大力开展数字化学校建造&#xff0c;在投入上都设有专项资金&#xff0c;很多学校现在信息化教育设施已满意现行教育教育要求。学校环绕数字化学校着力打造四个体系&#xff0c;即教育教务管理体系、协同…

UI组件库和内容文字的中英文切换

同时实现UI组件库(这里以ElementPlus为例)和内容文字的中英文切换 1. 安装vueI18n和element-plus pnpm i vue-i18n element-plus 2. 然后在项目中src目录下新建lang文件夹&#xff0c;里面新建en.ts和zh.ts还有index.ts index.ts import { createI18n } from vue-i18n impor…

Certbot免费证书的安装,使用,自动续期

首先你得先确认你得linux是那个操作系统&#xff0c;可以用这几个命令试一下。两个都可以试试 cat /etc/os-releaseuname -a然后看是Certbot得安装&#xff1a; CentOS: yum update yum install certbot -y Debian&#xff1a; apt update apt install certbot -y 有的云…

46. UE5 RPG 增加角色受击反馈

在前面的文章中&#xff0c;我们实现了对敌人的属性的初始化&#xff0c;现在敌人也拥有的自己的属性值&#xff0c;技能击中敌人后&#xff0c;也能够实现血量的减少。 现在还需要的就是在技能击中敌人后&#xff0c;需要敌人进行一些击中反馈&#xff0c;比如敌人被技能击中后…

XN297 2.4GHz 单片高速无线收发芯片

概述 XN297是一款工作在2.400~2.483GHz世界通用ISM频段的单片无线收发芯片。该芯片集成 射频收发器、频率发生器、晶体振荡器、调制解调器等功能模块&#xff0c;并且支持一对多组网和带 ACK的通信模式。发射输出功率、工作频道以及通信数据率均可配置。 主要特性 1、低功…

Linux-笔记 i2c-tools

1、i2c-tools介绍 1、在日常linux开发中&#xff0c;有时候需要确认i2c硬件是否正常连接&#xff0c;设备是否正常工作&#xff0c;设备的地址是多少等等&#xff0c;这里我们就需要使用一个用于测试I2C总线的工具——i2c-tools&#xff0c;i2c-tools原理是通过操作/dev 路径 …

Python专题:三、数字和运算(2)

目录 一、数学运算 二、赋值运算 一、数学运算 1、运算符号 加法 减法- 乘法* 除法/ 计算机中浮点数表示有精度限制&#xff0c;Python有限&#xff0c;所以近似取数 2、除法取整// Python2中 整数/整数 值为整数 Python3中 整数/整数 整数or浮点数 //计算除法对结果取…

segment anythin 新标注工具 paddleocr训练自己的数据

快递单ocr检测 1.总结2.需求3.方案4.面单定位4.1反转图片扩充数据集4.2新的标注方式4.3json2yolo4.4yolov5推理 5.paddleocr5.1 数据标注5.2 文本检测训练5.3 文本识别训练检测结果 1.总结 按照惯例&#xff0c;先吐槽一下。反正也没人看我比比歪歪。做事全部藏着掖着&#xf…

Redis-新数据类型-Bitmaps

新数据类型-Bitmaps 简介 在计算机中&#xff0c;用二进制&#xff08;位&#xff09;作为存储信息的基本单位&#xff0c;1个字节等于8位。 例如 “abc” 字符串是由 3 个字节组成&#xff0c;计算机存储时使用其二进制表示&#xff0c;"abc"分别对应的ASCII码是 …

苹果Mac用户下载VS Code(Universal、Intel Chip、Apple Silicon)哪个版本?

苹果macOS用户既可以下载通用版&#xff08;Universal&#xff09;&#xff0c;软件将自动检测用户的处理器并进行适配。 也可以根据型号下载对应CPU的版本&#xff1a; 使用Intel CPU的Mac电脑可下载Intel Chip版本&#xff1b; 使用苹果自研M系列CPU的Mac电脑下载Apple Si…

“漫画之家”|基于Springboot+vue的“漫画之家”系统(源码+数据库+文档)

“漫画之家”系统 目录 基于Springbootvue的“漫画之家”系统 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2后台模块 5.2.1管理员功能模块 5.2.2用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&a…

Final Draft 12 for Mac:高效专业剧本创作软件

对于剧本创作者来说&#xff0c;一款高效、专业的写作工具是不可或缺的。Final Draft 12 for Mac就是这样一款完美的选择。这款专为Mac用户设计的剧本创作软件&#xff0c;凭借其卓越的性能和丰富的功能&#xff0c;让您的剧本创作更加得心应手。 Final Draft 12支持多种剧本格…

完美匹配企业需求的FTP替代软件,需要具备哪些功能和价值?

FTP作为世界范围内第一个文件传输协议&#xff0c;已被广泛使用30多年&#xff0c;也是企业使用较多的一种方式。但在数字化转型的浪潮中&#xff0c;企业对文件传输的需求日益增长&#xff0c;FTP存在的弊端也逐渐成为企业发展的桎梏&#xff0c;比如安全性、稳定性、传输效率…

软件测试基础理论复习

什么是软件&#xff1f; 软件是计算机系统中与硬件相互依存的另一部分&#xff0c; 软件包括程序文档 什么是软件测试&#xff1f; &#xff08;1&#xff09;软件测试是在现有软件&#xff08;程序文档&#xff09;中寻找缺陷的过程&#xff1b; &#xff08;2&#xff0…

西部数据硬盘格式化了怎么恢复数据

在数字化时代&#xff0c;数据的重要性不言而喻。无论是个人珍贵的照片、视频&#xff0c;还是企业关键的业务文件&#xff0c;一旦丢失&#xff0c;都可能带来无法估量的损失。而硬盘作为数据存储的主要设备之一&#xff0c;其安全性与可靠性自然受到了广大用户的关注。然而&a…

会展服务预约小程序的作用是什么

年会、赛事、乐舞、招聘展览等多个场景都需要会展服务&#xff0c;商家需要将自己的服务推广出去获客转化&#xff0c;客户也需要找到合适靠谱的品牌&#xff0c;双方互相需求下&#xff0c;合理化线上运营触达非常重要。 运用【雨科】平台制作会展服务预约小程序&#xff0c;…

区块链的可扩展性三难问题

这个词是由以太坊的联合创始人Vitalik Buterin创造的&#xff0c;并提出了理想的区块链需要具备的三个特征&#xff1a;去中心化、可扩展性和安全性。 Vitalik还提出&#xff0c;区块链几乎不可能很好地实现所有这三个特征&#xff0c;所以会出现权衡。 因此&#xff0c;今天…

chatgpt快速搭建开发程序

程序开发中让GPT编写功能函数&#xff0c;懂原理的工程师只需要将GPT提供的命令码块按照项目对应的结构拆解后放置到项目文件夹对应的位置即可&#xff0c;高速高效快速搭建。 举例&#xff1a;

函数式接口-方法引用

定义 静态方法-方法引用 示例