LDAP

作者: Nick_4438 | 来源:发表于2021-11-27 16:06 被阅读0次

什么是LDAP

LDAP(Light Directory Access Portocol),它是基于X.500标准的轻量级目录访问协议。该协议可以提供目录服务。LDAP可以类比成为一个树形的数据库。其试用于更新少,读取多的场景,在软件系统中通常用来做一个统一的用户、组织管理。

基本概念

  • DN (distinguished name),可以理解成为LDAP中各个资源定位的ID,类似于文件路径,这个路径通常包含DC (Domain Component)、OU (Organizational Unit)、CN (Common Name)
  • DC (Domain Component),域名元素,通常是树形的根位置
  • OU (Organizational Unit),组织单元,
  • CM(common name),对象属性的通用名
  • o (Organization Name),
  • uid(userid),

LDAP的结构

image.png

在这里,我们举一个公司的例子,如上所示。

  • DN(Distinguished Name),数据的唯一标识,树形结构每个节点都有自己的唯一标识,如上图:
    • XXX集团 DN: dc=xxx集团,dc=com ,这是该树的根节点
    • 集团总部DN: dc=集团总部,dc=xxx集团,dc=com , 该节点的DN包含【 XXX集团 DN】的DN,所以可以看出这是【 XXX集团 DN】的子节点
    • 牛A公司DN: dc=牛A公司,dc=xxx集团,dc=com
    • 牛A公司研发部 DN: ou=研发部,ou=牛A公司,dc=xxx集团,dc=com
    • 牛A公司研发部 李四DN: cn=李四,cn=研发部,ou=牛A公司,dc=xxx集团,dc=com

容器openladp使用

  • 启动 openldap
# 挂载目录运行
docker run -itd -p 389:389 --name openldap \
-v /opt/data/ldap/database:/var/lib/ldap \
-v /opt/data/ldap/config:/etc/openldap/slapd.d \
--env LDAP_ORGANISATION="xyz" \
--env LDAP_DOMAIN="xyz.com" \
--env LDAP_ADMIN_PASSWORD="qiu11211" \
--detach osixia/openldap:1.5.0
# 测试,不挂载目录
docker run -itd -p 389:389 --name openldap \
--env LDAP_ORGANISATION="xyz" \
--env LDAP_DOMAIN="xyz.com" \
--env LDAP_ADMIN_PASSWORD="qiu11211" \
--detach osixia/openldap:1.5.0

配置LDAP组织者:LDAP_ORGANISATION
配置LDAP域:LDAP_DOMAIN
配置LDAP密码:LDAP_ADMIN_PASSWORD
默认登录用户名:admin

  • 启动phpldapadmin,其中10.54.16.23为openldap的启动IP
docker run -p 6443:443 \
        --env PHPLDAPADMIN_LDAP_HOSTS=192.168.3.156 \
        --detach osixia/phpldapadmin:0.9.0
login DN :cn=admin,dc=xyz,dc=com
Password: qiu11211
  • 可以自页面上创建操作节点

导入

在PHPLDAPadmin上可以导入组织架构,如下是一个例子:


image.png
dn: dc=gdy, dc=com 
dc: gdy  
objectClass: top  
objectClass: domain  
 
dn: ou=people, dc=gdy, dc=com 
ou: people  
objectClass: top  
objectClass: organizationalUnit  
 
dn: ou=group, dc=gdy, dc=com 
ou: group  
objectClass: top  
objectClass: organizationalUnit  

列子代码

  • 登录验证LDAP
package main

import (
    "fmt"
    "github.com/go-ldap/ldap/v3"
)

func main() {
    con, err := LoginBind("admin","qiu11211")
    fmt.Println(con.IsClosing())
    if err != nil {
        fmt.Println("V")
        fmt.Println(err)
    }
    fmt.Println("Exit")
}
// LoginBind  connection ldap server and binding ldap server
func LoginBind(ldapUser, ldapPassword string) (*ldap.Conn, error) {
    l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:%d", "127.0.0.1", 389))
    if err != nil {
        fmt.Errorf("conect error",err)
        return nil, err
    }
    _, err = l.SimpleBind(&ldap.SimpleBindRequest{
        Username: fmt.Sprintf("cn=%s,dc=demo,dc=com", ldapUser),
        Password: ldapPassword,
    })
    if err != nil {
        fmt.Println("ldap password is error: ", ldap.LDAPResultInvalidCredentials)
        return nil, err
    }
    fmt.Println(ldapUser,"登录成功")
    return l, nil
}
  • 添加用户例子
package main

import (
    "fmt"
    "github.com/go-ldap/ldap/v3"
)
type User struct {
    username    string
    password    string
    telephone   string
    emailSuffix string
    snUsername  string
    uid         string
    gid         string
}

func main() {
    fmt.Println("hello 1")
    con, err := LoginBind("admin","qiu11211")
    fmt.Println(con.IsClosing())
    if err != nil {
        fmt.Println("V")
        fmt.Println(err)
    }
    //1. add user
    var user User
    user.username="nick"
    user.password="admin123"
    user.snUsername="nick"
    user.uid="1000"
    user.gid="1000"
    user.emailSuffix="@qq.com"
    if err=user.addUser(con);err!=nil{
        fmt.Println(err)
    }
    fmt.Println("exit")

    //1. add user
    //var user1 User
    //user1.username="邱家洪"
    //user1.password="admin123"
    //user1.snUsername="邱家洪"
    //user1.uid="1000"
    //user1.gid="1000"
    //user1.emailSuffix="@qq.com"
    //if err=user1.addUser(con);err!=nil{
    //  fmt.Println(err)
    //}

}
// LoginBind  connection ldap server and binding ldap server
func LoginBind(ldapUser, ldapPassword string) (*ldap.Conn, error) {
    l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:%d", "127.0.0.1", 389))
    //l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "127.0.0.1", 389))
    if err != nil {
        fmt.Errorf("conect error",err)
        return nil, err
    }
    _, err = l.SimpleBind(&ldap.SimpleBindRequest{
        Username: fmt.Sprintf("cn=%s,dc=demo,dc=com", ldapUser),
        Password: ldapPassword,
    })
    if err != nil {
        fmt.Println("ldap password is error: ", ldap.LDAPResultInvalidCredentials)
        return nil, err
    }
    fmt.Println(ldapUser,"登录成功")
    return l, nil
}
func (user *User) addUser(conn *ldap.Conn) error {
    ldaprow := ldap.NewAddRequest(fmt.Sprintf("cn=%s,dc=demo,dc=com", user.username), nil)
    ldaprow.Attribute("userPassword", []string{user.password})
    ldaprow.Attribute("homeDirectory", []string{fmt.Sprintf("/home/%s", user.username)})
    ldaprow.Attribute("cn", []string{user.username})
    ldaprow.Attribute("uid", []string{user.username})
    ldaprow.Attribute("objectClass", []string{"shadowAccount", "posixAccount", "account"})
    ldaprow.Attribute("uidNumber", []string{"2201"})
    ldaprow.Attribute("gidNumber", []string{"2201"})
    ldaprow.Attribute("loginShell", []string{"/bin/bash"})

    if err := conn.Add(ldaprow); err != nil {
        return err
    }
    return nil
}

  • 删除用户
package main

import (
    "fmt"
    "github.com/go-ldap/ldap/v3"
)
type User struct {
    username    string
    password    string
    telephone   string
    emailSuffix string
    snUsername  string
    uid         string
    gid         string
}
func main() {
    fmt.Println("hello 1")
    con, err := LoginBind("admin","qiu11211")
    fmt.Println(con.IsClosing())
    if err != nil {
        fmt.Println("V")
        fmt.Println(err)
    }
    var user User
    user.username="marionxue"
    if err:=user.delUser(con);err!=nil{
        fmt.Println("用户删除失败")
    }
    fmt.Println(user.username,"用户删除成功!")
}
// LoginBind  connection ldap server and binding ldap server
func LoginBind(ldapUser, ldapPassword string) (*ldap.Conn, error) {
    l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:%d", "127.0.0.1", 389))
    //l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "127.0.0.1", 389))
    if err != nil {
        fmt.Errorf("conect error",err)
        return nil, err
    }
    _, err = l.SimpleBind(&ldap.SimpleBindRequest{
        Username: fmt.Sprintf("cn=%s,dc=demo,dc=com", ldapUser),
        Password: ldapPassword,
    })
    if err != nil {
        fmt.Println("ldap password is error: ", ldap.LDAPResultInvalidCredentials)
        return nil, err
    }
    fmt.Println(ldapUser,"登录成功")
    return l, nil
}

func (user *User) delUser(conn *ldap.Conn) error{
    ldaprow := ldap.NewDelRequest(fmt.Sprintf("cn=%s,dc=demo,dc=com",user.username),nil)

    if err:= conn.Del(ldaprow);err!=nil{
        return err
    }
    return nil
}

  • 遍历所有用户
package main

import (
    "fmt"
    "github.com/go-ldap/ldap/v3"
    "strings"
)
type User struct {
    username    string
    password    string
    telephone   string
    emailSuffix string
    snUsername  string
    uid         string
    gid         string
}

func main() {
    fmt.Println("hello 1")
    con, err := LoginBind("admin","qiu11211")
    fmt.Println(con.IsClosing())
    if err != nil {
        fmt.Println("V")
        fmt.Println(err)
    }
    //2. 遍历用户
    employees, err := GetEmployees(con)
    if err != nil {
        fmt.Println(err)
    }
    for _, employe := range employees {
        fmt.Println(employe)
    }
}
// LoginBind  connection ldap server and binding ldap server
func LoginBind(ldapUser, ldapPassword string) (*ldap.Conn, error) {
    l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:%d", "127.0.0.1", 389))
    //l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", "127.0.0.1", 389))
    if err != nil {
        fmt.Errorf("conect error",err)
        return nil, err
    }
    _, err = l.SimpleBind(&ldap.SimpleBindRequest{
        Username: fmt.Sprintf("cn=%s,dc=demo,dc=com", ldapUser),
        Password: ldapPassword,
    })
    if err != nil {
        fmt.Println("ldap password is error: ", ldap.LDAPResultInvalidCredentials)
        return nil, err
    }
    fmt.Println(ldapUser,"登录成功")
    return l, nil
}


func GetEmployees(con *ldap.Conn) ([]string, error) {
    var employees []string
    sql := ldap.NewSearchRequest("dc=demo,dc=com",
        ldap.ScopeWholeSubtree,
        ldap.NeverDerefAliases,
        0,
        0,
        false,
        "(objectClass=*)",
        []string{"dn", "cn", "objectClass"},
        nil)

    cur, err := con.Search(sql)
    if err != nil {
        return nil, err
    }

    if len(cur.Entries) > 0 {
        for _, item := range cur.Entries {
            cn := item.GetAttributeValues("cn")
            for _, iCn := range cn {
                employees = append(employees, strings.Split(iCn, "[")[0])
            }
        }
        return employees, nil
    }
    return nil, nil
}

  • 添加组
package main

import (
    "fmt"
    "github.com/go-ldap/ldap/v3"
)
type Group struct {
    username    string
}

func main() {
    fmt.Println("hello 1")
    con, err := LoginBind("admin","qiu11211")
    fmt.Println(con.IsClosing())
    if err != nil {
        fmt.Println("V")
        fmt.Println(err)
    }
    //1. add user
    var g Group
    g.username="crqu"
    if err=g.addGroup(con);err!=nil{
        fmt.Println(err)
    }
    fmt.Println("exit")

}
// LoginBind  connection ldap server and binding ldap server
func LoginBind(ldapUser, ldapPassword string) (*ldap.Conn, error) {
    l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:%d", "127.0.0.1", 389))
    if err != nil {
        fmt.Errorf("conect error",err)
        return nil, err
    }
    _, err = l.SimpleBind(&ldap.SimpleBindRequest{
        Username: fmt.Sprintf("cn=%s,dc=demo,dc=com", ldapUser),
        Password: ldapPassword,
    })
    if err != nil {
        fmt.Println("ldap password is error: ", ldap.LDAPResultInvalidCredentials)
        return nil, err
    }
    fmt.Println(ldapUser,"登录成功")
    return l, nil
}
//dn: ou=crqu,dc=demo,dc=com
//objectclass: organizationalUnit
//ou: crqu
func (group *Group) addGroup(conn *ldap.Conn) error {
    ldaprow := ldap.NewAddRequest(fmt.Sprintf("ou=%s,dc=demo,dc=com", group.username), nil)
    ldaprow.Attribute("objectClass", []string{"organizationalUnit"})
    ldaprow.Attribute("ou", []string{group.username})
    if err := conn.Add(ldaprow); err != nil {
        return err
    }
    return nil
}

  • 在新的组上面添加用户,含密码
package main

import (
    "fmt"
    "github.com/go-ldap/ldap/v3"
)
type User struct {
    username    string
}

func main() {
    fmt.Println("hello 1")
    con, err := LoginBind("admin","qiu11211")
    fmt.Println(con.IsClosing())
    if err != nil {
        fmt.Println("V")
        fmt.Println(err)
    }
    //1. add user
    var g User
    g.username="ming"
    if err=g.addUser(con);err!=nil{
        fmt.Println(err)
    }
    fmt.Println("exit")

}
// LoginBind  connection ldap server and binding ldap server
func LoginBind(ldapUser, ldapPassword string) (*ldap.Conn, error) {
    l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:%d", "127.0.0.1", 389))
    if err != nil {
        fmt.Errorf("conect error",err)
        return nil, err
    }
    _, err = l.SimpleBind(&ldap.SimpleBindRequest{
        Username: fmt.Sprintf("cn=%s,dc=demo,dc=com", ldapUser),
        Password: ldapPassword,
    })
    if err != nil {
        fmt.Println("ldap password is error: ", ldap.LDAPResultInvalidCredentials)
        return nil, err
    }
    fmt.Println(ldapUser,"登录成功")
    return l, nil
}
//dn: cn=nick,ou=crqu,dc=demo,dc=com
//cn: nick
//givenname: nick
//objectclass: inetOrgPerson
//objectclass: top
//sn: nick
func (group *User) addUser(conn *ldap.Conn) error {
    ldaprow := ldap.NewAddRequest(fmt.Sprintf("cn=%s,ou=crqu,dc=demo,dc=com", group.username), nil)
    ldaprow.Attribute("objectClass", []string{"inetOrgPerson","top"})
    ldaprow.Attribute("cn", []string{group.username})
    ldaprow.Attribute("givenname", []string{group.username})
    ldaprow.Attribute("sn", []string{group.username})
    // hua
    ldaprow.Attribute("userpassword", []string{"{MD5}pP2/vmpo8KAIjC2YxkRzEQ=="})
    if err := conn.Add(ldaprow); err != nil {
        return err
    }
    return nil
}

相关文章

网友评论

      本文标题:LDAP

      本文链接:https://www.haomeiwen.com/subject/clafxrtx.html