• springboot整合ldap


    LDAP介绍

    介绍

    LDAP是的一种管理系统。
    LDAP的存储结构为树状结构,由父节点、子节点、叶子节点组成。

    概念

    Entry

    条目,LDAP系统中最基本的颗粒,类似于数据库的记录。通常对LDAP的增删查改是以条目为基本对象。

    dn

    相当于条目的id,通常由包含ou、cn、dc等组成,例如:cn=test_test_1_6_210,ou=test3,ou=test2,ou=test_group,ou=Users。LDAP能通过dn清晰表示出该条目在LDAP系统中的位置。

    Attribute

    条目的属性

    用户属性

    userAccountControl

    属性标志十六进制值十进制值说明
    SCRIPT0x00011将运行登录脚本
    ACCOUNTDISABLE0x00022禁用用户帐户
    HOMEDIR_REQUIRED0x00088需要主文件夹
    LOCKOUT0x001016不需要密码
    PASSWD_NOTREQD0x002032用户不能更改密码。可以读取此标志,但不能直接设置它
    ENCRYPTED_TEXT_PWD_ALLOWED0x0080128用户可以发送加密的密码
    TEMP_DUPLICATE_ACCOUNT0x0100256此帐户属于其主帐户位于另一个域中的用户。此帐户为用户提供访问该域的权限,但不提供访问信任该域的任何域的权限。有时将这种帐户称为“本地用户帐户
    NORMAL_ACCOUNT0x0200512典型用户的默认帐户类型
    INTERDOMAIN_TRUST_ACCOUNT0x08002048对于信任其他域的系统域,此属性允许信任该系统域的帐户
    WORKSTATION_TRUST_ACCOUNT0x10004096运行 Microsoft Windows NT 4.0 Workstation、Microsoft Windows NT 4.0 Server、Microsoft Windows 2000 Professional 或 Windows 2000 Server 并且属于该域的计算机的计算机帐户
    SERVER_TRUST_ACCOUNT0x20008192属于该域的域控制器的计算机帐户
    DONT_EXPIRE_PASSWORD0x1000065536在该帐户上永远不会过期的密码
    MNS_LOGON_ACCOUNT0x20000131072MNS 登录帐户
    SMARTCARD_REQUIRED0x40000262144设置此标志后,将强制用户使用智能卡登录
    TRUSTED_FOR_DELEGATION0x80000524288设置此标志后,将信任运行服务的服务帐户(用户或计算机帐户)进行 Kerberos 委派。任何此类服务都可模拟请求该服务的客户端。若要允许服务进行 Kerberos 委派,必须在服务帐户的userAccountControl 属性上设置此标志
    NOT_DELEGATED0x1000001048576设置此标志后,即使将服务帐户设置为信任其进行 Kerberos 委派,也不会将用户的安全上下文委派给该服务
    USE_DES_KEY_ONLY0x2000002097152(Windows 2000/Windows Server 2003) 将此用户限制为仅使用数据加密标准 (DES) 加密类型的密钥。
    DONT_REQ_PREAUTH0x4000004194304(Windows 2000/Windows Server 2003) 此帐户在登录时不需要进行 Kerberos 预先验证
    PASSWORD_EXPIRED0x8000008388608(Windows 2000/Windows Server 2003) 用户的密码已过期
    TRUSTED_TO_AUTH_FOR_DELEGATION0x100000016777216(Windows 2000/Windows Server 2003) 允许该帐户进行委派。这是一个与安全相关的设置。应严格控制启用此选项的帐户。此设置允许该帐户运行的服务冒充客户端的身份,并作为该用户接受网络上其他远程服务器的身份验证
    ObjectClass

    条目的属性的集合

    Schema

    ObjectClass的集合。确保从外部导入数据到LDAP时的数据结构与现有数据结构一致性。

    backend

    读写数据的操作的单元模块

    database

    存储数据

    缩写

    缩写全称内容
    DCDomain Component域名的部分,其格式是将完整的域名分成几部分,如域名为example.com变成dc=example,dc=com
    UIDUser Id用户ID songtao.xu(一条记录的ID)
    OUOrganization Unit组织单位,组织单位可以包含其他各种对象(包括其他组织单元),如“oa组”(一条记录的所属组织)
    CNCommon Name公共名称,如“Thomas Johansson”(一条记录的名称)
    SNSurname姓,如“许”
    DNDistinguished Name“uid=songtao.xu,ou=oa组,dc=example,dc=com”,一条记录的位置(唯一)
    RDNRelative dn相对辨别名,类似于文件系统中的相对路径,它是与目录树结构无关的部分,如“uid=tom”或“cn= Thomas Johansson”

    springboot整合

    依赖

     <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-data-ldapartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4

    ladp版本跟随springboot版本即可

    配置项

    spring:
      ldap:
        urls: ldap://123:389
        base: dc=123-123,dc=cn
        username: cn=123,dc=123,dc=cn
        password: asdf
    
      jackson:
        serialization:
          # 不关闭jackson序列化,输出Name类型的dn会报错
          FAIL_ON_EMPTY_BEANS: false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    实体类

    base只填写至ou部分即可
    objectClass从这里找,此界面为php-ldap-admin
    php-ldap-admin

    成员

    package com.me.ldap.domain;
    
    import com.fasterxml.jackson.annotation.JsonIgnore;
    import org.springframework.ldap.odm.annotations.Attribute;
    import org.springframework.ldap.odm.annotations.Entry;
    import org.springframework.ldap.odm.annotations.Id;
    import org.springframework.ldap.support.LdapNameBuilder;
    
    import javax.naming.Name;
    import javax.naming.ldap.LdapName;
    import java.io.Serializable;
    import java.util.List;
    
    /**
     * @author Wuzhiming
     */
    @Entry(objectClasses = {"inetOrgPerson"}, base = "ou=Users")
    public class Person implements Serializable {
    
    
        private static final long serialVersionUID = 2537331577057988415L;
        @Id
        private Name dn;
    
        /**
         * 用户唯一标识
         */
        @Attribute(name = "cn")
        private String cn;
    
        @Attribute(name = "sn")
        private String sn;
    
        @Attribute(name = "userPassword")
        private String userPassword;
    
        @Attribute(name = "ou")
        private String groupName;
    
        @Attribute(name = "userAccountControl")
        private String userAccountControl;
    
        public String getGroupName() {
            return groupName;
        }
    
        public void setGroupName(String groupName) {
            this.groupName = groupName;
        }
    
        public String getUserAccountControl() {
            return userAccountControl;
        }
    
        public void setUserAccountControl(String userAccountControl) {
            this.userAccountControl = userAccountControl;
        }
    
        public Person(String cn) {
            LdapName dn = LdapNameBuilder.newInstance()
                    .add("o", "Users")
                    .add("cn", cn)
                    .add("dc", "yuang-group")
                    .build();
            this.dn = dn;
        }
    
        public Person(String cn, String groupName) {
            LdapName dn = LdapNameBuilder.newInstance()
                    .add("o", groupName)
                    .add("cn", cn)
                    .add("dn", "Users")
                    .add("dc", "yuang-group")
                    .build();
            this.dn = dn;
        }
    
        public Person() {
        }
    
        /**
         * getter
         */
        public Name getDn() {
            return dn;
        }
    
        public String getCn() {
            return cn;
        }
    
        public String getSn() {
            return sn;
        }
    
        public String getUserPassword() {
            return userPassword;
        }
    
        /** setter */
        public void setDn(Name dn) {
            this.dn = dn;
        }
    
        public void setCn(String cn) {
            this.cn = cn;
        }
    
        public void setGroup(String groupName) {
            if (this.dn == null) {
                LdapName dn = LdapNameBuilder.newInstance()
                        .add("ou","Users")
                        .add("ou", groupName)
                        .add("cn",cn)
                        .build();
                this.dn = dn;
            }
        }
        public void setGroup(List<String> groupNameList) {
    
            if (this.dn == null) {
                LdapNameBuilder builder = LdapNameBuilder.newInstance()
                        .add("ou", "Users");
                for (String groupName : groupNameList) {
                    builder=builder.add("ou",groupName);
                }
                LdapName dn = builder.add("cn", cn).build();
                this.dn = dn;
            }
        }
    
        public void setSn(String sn) {
            this.sn = sn;
        }
    
        public void setUserPassword(String userPassword) {
            this.userPassword = userPassword;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "dn=" + dn +
                    ", cn='" + cn + '\'' +
                    ", sn='" + sn + '\'' +
                    ", userPassword='" + userPassword + '\'' +
                    ", groupName='" + groupName + '\'' +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151

    成员组

    package com.me.ldap.domain;
    
    import org.springframework.ldap.odm.annotations.Attribute;
    import org.springframework.ldap.odm.annotations.Entry;
    import org.springframework.ldap.odm.annotations.Id;
    import org.springframework.ldap.support.LdapNameBuilder;
    
    import javax.naming.Name;
    import java.util.List;
    
    @Entry(objectClasses = {"organizationalUnit","top"},base = "ou=Users")
    public class Group {
        @Id
        private Name dn;
    
        @Attribute(name = "ou")
        private String name;
    
        public Name getDn() {
            return dn;
        }
    
        public void setGroupName(List<String> groupNameList) {
            if(this.dn==null){
                LdapNameBuilder builder = LdapNameBuilder.newInstance();
                builder.add("ou","Users");
                for (String groupName : groupNameList) {
                    builder=builder.add("ou",groupName);
                }
                dn=builder.build();
            }
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Group{" +
                    "dn=" + dn +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    前端传参接收类

    用户
    package com.me.ldap.domain.param;
    
    import com.fasterxml.jackson.annotation.JsonIgnore;
    import lombok.Data;
    import org.springframework.ldap.odm.annotations.Attribute;
    import org.springframework.ldap.odm.annotations.Entry;
    import org.springframework.ldap.odm.annotations.Id;
    import org.springframework.ldap.support.LdapNameBuilder;
    
    import javax.naming.Name;
    import java.io.Serializable;
    import java.util.List;
    
    /**
     * @author Wuzhiming
     */
    @Data
    public class AddPersonParam implements Serializable {
    
    
        private static final long serialVersionUID = -3761043026736955966L;
    
        private List<String> groupName;
    
        private String cn;
    
        private String sn;
    
        private String userPassword;
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    用户组

    package com.me.ldap.domain.param;
    
    import lombok.Data;
    
    import java.util.List;
    
    /**
     * @author Wuzhiming
     */
    @Data
    public class AddGroupParam {
    
        private List<String> groupNameList;
        
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    增删查改

    查询
    查询单个用户
        public Person getPersonByCn(String cn) {
            Person cn1 = ldapTemplate.findOne(query().where("cn").is(cn), Person.class);
            return cn1;
        }
    
    • 1
    • 2
    • 3
    • 4
    查询所有用户(只包含在base下的)
        public List<Person> getAll() {
            return ldapTemplate.findAll(Person.class);
        }
    
    • 1
    • 2
    • 3
    新增
        /**
         * 创建用户
         *
         * @param personParam
         */
        public void create(AddPersonParam personParam) {
            Person person = new Person();
            BeanCopier beanCopier = BeanCopier.create(AddPersonParam.class, Person.class, false);
            beanCopier.copy(personParam, person, null);
            person.setGroup(personParam.getGroupName());
            System.out.println(person);
            ldapTemplate.create(person);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    {
      "groupName": ["test_group","test2","test3"],
      "cn": "test_test_1_6_20",
      "sn": "114851418",
      "userPassword": "123456abcABC."
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    注意事项
    1. 只能在${base}组和以下级别的节点上创建用户。
    2. 添加用户前必须先创建用户组,create()不能级联创建用户组。
    3. b a s e 组的级别,即在 {base}组的级别,即在 base组的级别,即在{base}级别以下的成员组中加入用户,则需要写上此成员组及所有成员组名(${base}除外)
    4. cn必须保证全局唯一
    删除
    删除本节点
        public void deletePerson(String personCn) {
            Person person = this.getPersonByCn(personCn);
            System.out.println(person);
            ldapTemplate.delete(person);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    注意事项
    1. 删除本节点时,本节点不能有任何子节点,否则会报错
    级联删除
            Group group = new Group();
            BeanCopier beanCopier = BeanCopier.create(AddGroupParam.class, Group.class, false);
            beanCopier.copy(param, group, null);
            group.setGroupName(param.getGroupNameList());
            System.out.println(group);
            ldapTemplate.unbind(group.getDn(),true);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 相关阅读:
    是时候,升级你的 Windows 了「GitHub 热点速览」
    无代码开发平台应用可见权限设置入门教程
    【云原生 | Kubernetes 系列】--Gitops持续交付 ArgoCD自动同步策略
    使用数据库实现增删改查
    追踪这9大关键DTC指标,将帮助你建立势头并释放增长
    程序员脱单
    mybatis
    单片机硬件内部结构
    JUC锁:核心类AQS源码详解
    CentOS 中下载安装Nginx
  • 原文地址:https://blog.csdn.net/qq_22899047/article/details/126786947