goalng 如何获取 ldap 服务器的数据?

简介: goalng 如何获取 ldap 服务器的数据?

我们工作在和其他组织配合时,我们可能不是作为服务器搭建的一方,而是属于客户端的一方,需要去获取服务器的组织结构,按照某些条件去获取服务器的数据,也可以是同步组织结构

虽然说 golang 的数据结构没有 c++ 那么丰富,不过对于这个 ldap 还是有相应的库来进行处理的

官方文档地址:https://pkg.go.dev/gopkg.in/ldap.v3

我们也可以下载 github 上面的这个库

go get github.com/go-ldap/ldap/v3

golang 对于 ldap 库最新的版本是 Version: v3.1.0

开始编码

我们来写一个 demo ,获取我们上次搭建的 ldap 服务器上的组织结构

这是我们简单搭建的 ldap 服务器,可以使用 LDAP Admin 可视化管理工具来查看具体的页面效果

我们把这个库下载下来后,我们的编码思路如下:

  • 填写 ldap 服务器地址以及填写相应的管理员信息,与 ldap 服务器建立连接
  • 编写查询请求,并开始向 ldap 服务器进行查询
  • 将查询结构,按照 ldap v3 库提供的方式 打印出效果来

连接 服务器

我们可以使用 func DialURL(addr string, opts ...DialOpt) (*Conn, error) 函数来与 ldap 服务器建立连接

ml, err := ldap.DialURL("ldap://xxxx")
  if err != nil {
    log.Fatal(err)
  }
  defer ml.Close()

我们填入的地址中,可以不用输入端口号,库函数已经有给我们做好处理,我们可以来看看源码

DialURL 函数用于连接 ldap 服务器,连接成功会给我们返回一个新的连接

我们可以继续看一下这个函数调用 c, err := dc.dial(u)

golang 的库会根据我们填写的地址是 ldap 还是 ldaps 来判断是做加密传输还是不加密传输,与之对应的就是访问不加密的用 389 端口加密的就使用 636 端口

添加管理员绑定信息

我们添加的 ldap 域信息为:dc=xiaomotong,dc=com

我的管理员是:cn=admin,dc=xiaomotong,dc=com

_, err = ml.SimpleBind(&ldap.SimpleBindRequest{
    Username: "cn=admin,dc=xiaomotong,dc=com",
    Password: "123123",
  })
  if err != nil {
    log.Fatalf("Failed to bind: %s\n", err)
  }
  fmt.Println("connect successfully !!")

来看看实际的 SimpleBindRequest 数据结构

// SimpleBindRequest represents a username/password bind operation
type SimpleBindRequest struct {
  // Username is the name of the Directory object that the client wishes to bind as
  Username string
  // Password is the credentials to bind with
  Password string
  // Controls are optional controls to send with the bind request
  Controls []Control
  // AllowEmptyPassword sets whether the client allows binding with an empty password
  // (normally used for unauthenticated bind).
  AllowEmptyPassword bool
}
  • Username
  • Password

客户端需要绑定的域用户和密码

  • Controls

需要绑定请求的控件

  • AllowEmptyPassword

是否允许空密码,若是空密码,一般是绑定一个未授权的用户

编写查询请求,并开始查询 ldap 服务器

searchRequest := ldap.NewSearchRequest(
    "dc=xiaomotong,dc=com",
    ldap.ScopeWholeSubtree,
    ldap.NeverDerefAliases,
    0,
    0,
    false,
    "(ou=People)",
    []string{},
    nil,
  )
  searchResult, err := ml.Search(searchRequest)
  if err != nil {
    log.Println("can't search ", err.Error())
  }
  log.Printf("%d", len(searchResult.Entries))

编写查询请求,也就是简单的给我们的结构体进行一个负值操作,填写好对相应的参数,即可开始查询,一起来看看这个结构体NewSearchRequest

基本上就是填写相应的域信息

  • BaseDN , 一个域唯一的标识
  • scope 范围的选择,我们默认选择ScopeWholeSubtree ,查询所有的子树
  • DerefAliases , SizeLimit,TimeLimit,TypesOnly 填写默认值即可
  • Filter , 查询需要的过滤条件,可以按照我们的实际情况写条件,就像写查询数据库的条件一样,这里不能为空,否则会程序崩溃
F:\codegitee\golang_study\later_learning\ldap_test>go run main.go
connect successfully !!
2021/11/06 21:07:59 can't search  LDAP Result Code 201 "Filter Compile Error": ldap: error parsing filter
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x4 pc=0xa33cef]
goroutine 1 [running]:
main.main()
        F:/codegitee/golang_study/later_learning/ldap_test/main.go:40 +0x24f
exit status 2
  • Attributes , 需要返回的属性有哪些,是一个切片,如果我们默认填空,则会返回所有属性

查看对应的 Search 函数源码

代码的大致逻辑是,doRequest 将数据组包向 ldap 服务器发送请求,请求成功之后,将响应的数据按照 tag 不同的内容进行解析

最终返回一个 *SearchResult 查询结果的指针

输入查询信息

for _, item := range searchResult.Entries {
   item.Print()
   fmt.Printf("\n\n")
}

上图源码我们可以看到输出查询信息就是遍历一下 searchResult.Entries ,我们可以来看看对应的数据结构

我们可以看到结果里面,有一个 Entries []*Entry 是一个切片,里面放了多个 *Entry , 在 ldap 服务器中, 1 个 Entry 就代表一条唯一的记录

Entry 结构体就是对应的 DN,一条记录唯一的辨别名 , 和他涉及的属性

EntryAttribute 属性结构体中,我们可以看到 有 Name ,有 Values ,这里就是对应我们之前说到的 RDN,也就是一个键值对,多个键值对组成一个 DN

最终我们来查看一下效果

>go run main.go
connect successfully !!
2021/11/06 21:20:58 1
DN: ou=People,dc=xiaomotong,dc=com
objectClass: [organizationalUnit]
ou: [People]

结果是输出了 1 条信息,没错,因为我们的 ou=people 只有 1条记录,如果我们需要查询整个 ldap服务器的所有数据,则我们可以将上述代码的 Filter 位置,修改成 objectClass=*

解释上述结果:

  • DN 表示唯一的记录,是辨别名的意思
  • objectClass 是一个类,这里对应的是 organizationalUnit ,表示组织单元OU,可以理解为 组
  • ou: [People] 指的是这个 ou 对应的名字是 People

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

相关文章
|
30天前
|
存储 数据挖掘
服务器数据恢复—用RAID5阵列中部分盘重建RAID5如何恢复原raid5阵列数据?
服务器数据恢复环境: 一台服务器挂接一台存储,该存储中有一组由5块硬盘组建的RAID5阵列。 服务器故障: 存储raid5阵列中有一块硬盘掉线。由于RAID5的特性,阵列并没有出现问题。工作一段时间后,服务器出现故障,用户方请人维修。维修人员在没有了解故障磁盘阵列环境的情况下,用另外4块硬盘(除去掉线的硬盘)重新创建了一组全新的RAID5阵列并完成数据同步,导致原raid5阵列数据全部丢失。
|
2月前
|
存储 弹性计算 缓存
阿里云服务器ECS通用型实例规格族特点、适用场景、指标数据解析
阿里云服务器ECS提供了多种通用型实例规格族,每种规格族都针对不同的计算需求、存储性能、网络吞吐量和安全特性进行了优化。以下是对存储增强通用型实例规格族g8ise、通用型实例规格族g8a、通用型实例规格族g8y、存储增强通用型实例规格族g7se、通用型实例规格族g7等所有通用型实例规格族的详细解析,包括它们的核心特点、适用场景、实例规格及具体指标数据,以供参考。
阿里云服务器ECS通用型实例规格族特点、适用场景、指标数据解析
|
1月前
|
Python
Flask学习笔记(三):基于Flask框架上传特征值(相关数据)到服务器端并保存为txt文件
这篇博客文章是关于如何使用Flask框架上传特征值数据到服务器端,并将其保存为txt文件的教程。
31 0
Flask学习笔记(三):基于Flask框架上传特征值(相关数据)到服务器端并保存为txt文件
|
2月前
|
存储 弹性计算 安全
阿里云服务器ECS计算型实例规格族特点、适用场景、指标数据参考
阿里云服务器ECS提供了丰富的计算型实例规格族,专为满足不同场景下的高性能计算需求而设计。包括计算型实例规格族c8y、计算型实例规格族c7、计算型实例规格族c8i等热门计算型实例规格,以及网络增强型的c7nex、密集计算型的ic5等其他计算型实例规格,每一种规格族都经过精心优化,确保在计算性能、存储效率、网络吞吐和安全特性等方面达到最佳平衡。本文将详细解析阿里云服务器ECS中的多个计算型实例规格族,包括它们的核心特点、适用场景、实例规格及具体指标数据,为用户在云计算资源选型时提供全面参考。
阿里云服务器ECS计算型实例规格族特点、适用场景、指标数据参考
|
1月前
|
SQL 分布式计算 关系型数据库
Hadoop-21 Sqoop 数据迁移工具 简介与环境配置 云服务器 ETL工具 MySQL与Hive数据互相迁移 导入导出
Hadoop-21 Sqoop 数据迁移工具 简介与环境配置 云服务器 ETL工具 MySQL与Hive数据互相迁移 导入导出
57 3
|
1月前
|
弹性计算 Linux 数据库
阿里云国际版如何迁移Linux云服务器系统盘中的数据
阿里云国际版如何迁移Linux云服务器系统盘中的数据
|
2月前
|
存储 弹性计算 网络协议
阿里云ECS内存型实例规格族特点、适用场景、指标数据参考
阿里云ECS提供了多样化的内存型实例规格族,专为需要高性能内存资源的应用场景设计。从最新的r8a系列到经过优化的re6p系列,旨在提供稳定、高效且安全的计算环境。这些实例不仅具备强大的计算性能与内存配比,还通过支持ESSD云盘和高效网络协议,显著提升了存储I/O能力和网络带宽,适用于大数据分析、高性能数据库、内存密集型应用等多种场景,为用户带来卓越的计算体验。本文将详细解析阿里云ECS中的多个内存型实例规格族,包括它们的核心特点、适用场景、实例规格及具体指标数据,为用户在云计算资源选型时提供参考。
|
3月前
|
缓存 运维 监控
打造稳定高效的数据引擎:数据库服务器运维最佳实践全解析
打造稳定高效的数据引擎:数据库服务器运维最佳实践全解析
|
3月前
|
SQL 数据库 数据安全/隐私保护
服务器数据恢复—raid5阵列故障因操作不当导致数据无法恢复的案例
服务器数据恢复环境: 一台服务器中有一组由4块SCSI硬盘组建的raid5磁盘阵列,划分了一个逻辑卷,操作系统为WINDOWS SERVER,作为SQL SERVER服务器使用。 服务器故障: 运行过程中该服务器raid5磁盘阵列瘫痪,管理员检查服务器发现raid5阵列中已经有3块磁盘离线。管理员选择其中2块离线硬盘进行强制上线操作,强制上线后操作系统无法启动。使用WINPE光盘启动操作系统后,可以看到数据。
|
3月前
|
JSON API 数据格式
基于服务器响应的实时天气数据进行JSON解析的详细代码及其框架
【8月更文挑战第25天】这段资料介绍了一个使用Python从服务器获取实时天气数据并解析JSON格式数据的基本框架。主要分为三个部分:一是安装必要的`requests`库以发起HTTP请求获取数据,同时利用Python内置的`json`库处理JSON数据;二是提供了具体的代码实现,包括获取天气数据的`get_weather_data`函数和解析数据的`parse_weather_data`函数;三是对代码逻辑进行了详细说明,包括如何通过API获取数据以及如何解析这些数据来获取温度和天气描述等信息。用户需要根据实际使用的天气API调整代码中的API地址、参数和字段名称。
下一篇
无影云桌面