LDAP学习记录

概述

LDAP是轻量目录访问协议,英文全称是Lightweight Directory Access Protocol.
其分为客户端和服务端.
在服务端, 对外是一棵树, 每个节点可以附加一些属性, 这些属性有内置的, 也有自定义的.

LDAP Admin Tool可以连接上(类似于navicat一样可以连接mysql-server) ldap服务端, 树结构及属性一目了然:
(图)

概念

ldap中有一些基本概念需要说一下:

  • dc: 域名部分, 折开书写, 以example.com为例子, 书写形式为: dc=example,dc=com
  • ou: 个人理解为分组(树的分支), 可以为多个(树枝上还有小树枝), 如:ou=Department,ou=RD,ou=devops表示部门下的研发组下的devops组.
  • cn: Common Name公共名称
  • sn: Surname, 姓
  • dn: Distinguished Name, 如uid=tom,ou=oa,dc=example,dc=com,一条记录的位置(唯一), 是一棵树中节点的访问路径.
  • rdn: Relative dn.相对辨别名,类似于文件系统中的相对路径,它是与目录树结构无关的部分,如uid=tom
  • Entry: 实体, 其实就是节点, Entry上可以有多个属性, 属性有内置的, 也可再自定义.

说明

实体(Entry)可以分多级(类似于公司下有部门, 部门下有小组这样的关系)

golang操作ldap示例

package main

import (
	"fmt"
	"os"
	"strings"

	"gitlab.example.com/example/common/log"
	"github.com/go-ldap/ldap/v3"
)

func ldapConn() (l *ldap.Conn, err error) {
	l, err = ldap.Dial("tcp", "192.168.1.2:389")
	if err != nil {
		panic(err)
	}
	err = l.Bind("cn=admin,dc=example,dc=com", "example@1234")
	if err != nil {
		panic(err)
	}
	return
}

func LdapSearch(searchRequest *ldap.SearchRequest) (sr *ldap.SearchResult, err error) {
	l, err := ldapConn()
	if err != nil {
		log.Error("failed to connect openldap,err:", err)
		return
	}
	defer l.Close()
	sr, err = l.Search(searchRequest)

	if err != nil && !strings.Contains(err.Error(), ldap.LDAPResultCodeMap[ldap.LDAPResultNoSuchObject]) {
		log.Error("failed to search openldap,err:", err)
		return
	}

	return
}

var (
	BaseDnGroupCustomer = "cn=Customer,ou=Account,dc=example,dc=com"
)

func searchByUUID(uuid string) (err error) {
	searceRequest := &ldap.SearchRequest{
		BaseDN:       BaseDnGroupCustomer,
		Scope:        ldap.ScopeWholeSubtree,
		DerefAliases: ldap.NeverDerefAliases,
		SizeLimit:    0,
		TimeLimit:    0,
		Attributes:   []string{"entryUUID"},
		TypesOnly:    false,
		Filter:       fmt.Sprintf(`(entryUUID=%s)`, uuid),
	}

	r, err := LdapSearch(searceRequest)
	if err != nil {
		return
	}

	if len(r.Entries) == 0 {
		err = fmt.Errorf("no such user: %s", uuid)
		return
	}

	dn := r.Entries[0].DN

	fmt.Println("attrs:")
	for _, v := range r.Entries[0].Attributes {
		fmt.Println(v.Name, v.Values)
	}
	fmt.Println("attrs end")

	// 只留下"uid=abao-c2,uid=abao"
	uidsStr := strings.TrimSuffix(dn, BaseDnGroupCustomer)
	if len(uidsStr) == 0 {
		err = fmt.Errorf("empty uid got")
		return
	}
	return
}

func main() {
	err := searchByUUID("some-uuid")
	if err != nil {
		panic(err)
	}
}

客户端

除了用编程语言操作ldap, 还有一些实用的客户端, 比如我用过的

参考

(未完待续)

发布了231 篇原创文章 · 获赞 77 · 访问量 52万+

猜你喜欢

转载自blog.csdn.net/butterfly5211314/article/details/103171184