惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
量子位
M
MIT News - Artificial intelligence
Y
Y Combinator Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Google DeepMind News
Google DeepMind News
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
雷峰网
雷峰网
I
InfoQ
罗磊的独立博客
博客园 - 聂微东
酷 壳 – CoolShell
酷 壳 – CoolShell
大猫的无限游戏
大猫的无限游戏
D
Docker
H
Hackread – Cybersecurity News, Data Breaches, AI and More
腾讯CDC
博客园 - 三生石上(FineUI控件)
The GitHub Blog
The GitHub Blog
K
Kaspersky official blog
P
Privacy & Cybersecurity Law Blog
S
SegmentFault 最新的问题
T
Threat Research - Cisco Blogs
H
Help Net Security
小众软件
小众软件
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
C
CERT Recently Published Vulnerability Notes
WordPress大学
WordPress大学
T
Tenable Blog
T
The Blog of Author Tim Ferriss
C
Cisco Blogs
Simon Willison's Weblog
Simon Willison's Weblog
博客园 - Franky
A
Arctic Wolf
T
Threatpost
Scott Helme
Scott Helme
C
Cybersecurity and Infrastructure Security Agency CISA
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
The Exploit Database - CXSecurity.com
G
GRAHAM CLULEY
Security Latest
Security Latest
Spread Privacy
Spread Privacy
L
LINUX DO - 热门话题
V
Vulnerabilities – Threatpost
P
Privacy International News Feed
S
Schneier on Security
Latest news
Latest news
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com

二丫讲梵

学习周刊-总第258期-2026年第15周 学习周刊-总第257期-2026年第14周 学习周刊-总第256期-2026年第13周 学习周刊-总第255期-2026年第12周 学习周刊-总第254期-2026年第11周 学习周刊-总第253期-2026年第10周 临时插播一条羊毛,免费领取450元大模型API代金券 学习周刊-总第252期-2026年第09周 学习周刊-总第251期-2026年第08周 学习周刊-总第250期-2026年第07周 学习周刊-总第249期-2026年第06周 诚邀评论,聊聊你所知欲知的我 学习周刊-总第248期-2026年第05周 我的QQ动态之2015年 我的QQ动态之2014年 我的QQ动态之2013年 我的QQ动态之2012年 我的QQ动态-2010-2011年 我的QQ动态-创栏小叙 学习周刊-总第247期-2026年第04周 Nexus社区版权益阉割--一文告诉你有哪些版本可以选择 学习周刊-总第246期-2026年第03周 学习周刊-总第245期-2026年第02周 学习周刊-总第244期-2026年第01周 学习周刊-总第243期-2025年第52周 学习周刊-总第242期-2025年第51周 开源项目ZenOps:带你领略禅意运维 学习周刊-总第241期-2025年第50周 用京东金融,享负债人生 学习周刊-总第240期-2025年第49周 学习周刊-总第239期-2025年第48周 整理我在静态服务透明代理上的极致求索之路,最后一个你绝想不到 学习周刊-总第238期-2025年第47周 我们输了,但收获颇多 太多了,太多了 学习周刊-总第237期-2025年第46周 学习周刊-总第236期-2025年第45周 学习周刊-总第235期-2025年第44周 二五年国庆二三事 学习周刊-总第234期-2025年第43周 学习周刊-总第233期-2025年第42周 学习周刊-总第232期-2025年第41周 学习周刊-总第231期-2025年第40周 学习周刊-总第230期-2025年第39周 西湖毅行 2025年开源世界逸闻三则 学习周刊-总第229期-2025年第38周 手抄《与妻书》 CNB开发与构建基于docker-cache缓存复用的配置实践心得 学习周刊-总第228期-2025年第37周 父亲善行录 学习周刊-总第227期-2025年第36周 带你认识我之看看我的高中同学录(其二) 学习周刊-总第226期-2025年第35周 带你认识我之看看我的高中同学录(其一) 认识神级MCP工具系列--用anyquery和数据库交互 学习周刊-总第225期-2025年第34周 学习周刊-总第224期-2025年第33周 学习周刊-总第223期-2025年第32周 学习周刊-总第222期-2025年第31周 学习周刊-总第221期-2025年第30周 CNB云原生开发环境届的瑞士军刀,详解qifei项目 vuepress-vdoing主题配置自建不蒜子统计 学习周刊-总第220期-2025年第29周 写在博客发表文章1000篇的节点 从claude cli的体验聊聊最大的敌人是我们自己的成见 学习周刊-总第219期-2025年第28周 学习周刊-总第218期-2025年第27周 学习周刊-总第217期-2025年第26周 理论正确,事实错误 学习周刊-总第216期-2025年第25周 学习周刊-总第215期-2025年第24周 学习周刊-总第214期-2025年第23周 学习周刊-总第213期-2025年第22周 学习周刊-总第212期-2025年第21周 从赵心童世锦赛夺冠聊聊我的斯诺克情缘 学习周刊-总第211期-2025年第20周 记录二五年五一之短暂回归家庭 学习周刊-总第210期-2025年第19周 学习周刊-总第209期-2025年第18周 学习周刊-总第208期-2025年第17周 Go开发实践之Gin框架将前端的dist目录embed到二进制 学习周刊-总第207期-2025年第16周 近期关于cobra库的一些实践心得总结 学习周刊-总第206期-2025年第15周 我的嗜好--嗑瓜子 记大宝参加幼儿园组织的清明烈士陵园扫墓活动 学习周刊-总第205期-2025年第14周 学习周刊-总第204期-2025年第13周 前端开发小笔记--在数组中给字段添加值与删除字段的操作 学习周刊-总第203期-2025年第12周 人生实苦,何以自渡 学习周刊-总第202期-2025年第11周 近期发现的一些优秀的工具提名(一) 学习周刊-总第201期-2025年第10周 学习周刊-总第200期-2025年第09周 记一次女友喝醉使我忍术破功 爱情风波--一次分手又复合的经历 学习周刊-总第199期-2025年第08周 整理我的信息源
openLDAP入门系列笔记第二篇--简单认识objectCLass以及常见应用
二丫讲梵 · 2022-07-18 · via 二丫讲梵

本文我们来认识理解一个很重要的概念:objectCLass,其实了解它是很难的,网上不少介绍的文章也讲的云里雾里,看完之后反而更加迷糊,本文将不求完全讲透,但求你看完会用。

# 理解

我们可以把 objectCLass 的属性值理解为是 ldap 中的一种模板,模板定义哪些信息可以存取,哪些信息不可以存储在目录树中。

因此,我们在实际使用过程中会发现,声明了不同的 objectCLass 时,可能添加某个字段就会报错了。

# objectClass 的分类

  • 结构型(structural):如 person 和 oraganizationUnit
  • 辅助型(auxiliary):如 extensibleObject
  • 抽象型(abstract):如 top,抽象型的 objectClass 不能直接使用。

# objectCLass 的列表

很多文档在介绍 objectCLass 列表时会说,常见的 objectCLass,我想说,你看了如下列表之后,内心的 OS 应该是:他妹的,一个也不常见。

但我还是列出一下,让你大概有个感受:

  • alias
  • applicationEntity
  • dSA
  • applicationProcess
  • bootableDevice
  • certificationAuthority
  • certificationAuthority-V2
  • country
  • cRLDistributionPoint
  • dcObject
  • device
  • dmd
  • domain
  • domainNameForm
  • extensibleObject
  • groupOfNames
  • groupOfUniqueNames
  • ieee802Device
  • ipHost
  • ipNetwork
  • ipProtocol
  • ipService
  • locality
  • dcLocalityNameForm
  • nisMap
  • nisNetgroup
  • nisObject
  • oncRpc
  • organization
  • dcOrganizationNameForm
  • organizationalRole
  • organizationalUnit
  • dcOrganizationalUnitNameForm
  • person
  • organizationalPerson
  • inetOrgPerson
  • uidOrganizationalPersonNameForm
  • residentialPerson
  • posixAccount
  • posixGroup
  • shadowAccount
  • strongAuthenticationUser
  • uidObject
  • userSecurityInformation

如果你部署了 phpldapAdmin,那么在你的 URL 后边拼上 /cmd.php?cmd=schema&server_id=1,则可以看到详细的列表。

访问:http://localhost:8091/cmd.php?cmd=schema&server_id=1 (opens new window)

OK,现在你大概看到了 objectCLass 长什么样子,那么请你忘记它,只需要看下边一个能够走通的可用的实践即可。

# 应用

实际应用中,其实根本不需要理解,或者认识那么多的概念,你只需要记住一种适合自己场景的 objectCLass 即可,那么接下来我介绍一下个人理解的,原则上来说,你直接照搬就可以了。

# 用户

在 go-ldap-admin 项目中,创建一个用户条目使用的方式如下:

func (x UserService) Add(user *model.User) error {
	add := ldap.NewAddRequest(user.UserDN, nil)
	add.Attribute("objectClass", []string{"inetOrgPerson"})
	add.Attribute("cn", []string{user.Username})
	add.Attribute("sn", []string{user.Nickname})
	add.Attribute("businessCategory", []string{user.Departments})
	add.Attribute("departmentNumber", []string{user.Position})
	add.Attribute("description", []string{user.Introduction})
	add.Attribute("displayName", []string{user.Nickname})
	add.Attribute("mail", []string{user.Mail})
	add.Attribute("employeeNumber", []string{user.JobNumber})
	add.Attribute("givenName", []string{user.GivenName})
	add.Attribute("postalAddress", []string{user.PostalAddress})
	add.Attribute("mobile", []string{user.Mobile})
	add.Attribute("uid", []string{user.Username})
	add.Attribute("userPassword", []string{tools.NewParPasswd(user.Password)})
	return common.LDAP.Add(add)
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

此处可以看到开头声明的 objectCLass 为:inetOrgPerson

那么接下来,我们访问这个链接来查看该属性的具体含义。

访问:http://localhost:8091/cmd.php?cmd=schema&server_id=1&view=objectclasses&viewvalue=inetorgperson (opens new window)

通过这张图,我们能够更加清晰地理解 objectCLass 这一概念的含义,比如 inetOrgPerson 这个模板,就声明了如上所示的这些属性约定,这些属性我们就可以对照着openLDAP 的基础概念里边的内容进行查阅分析了。

表格左侧是必须存在的属性,右侧则是可选使用的属性。

go-ldap-admin 选择了一些日常工作中常用的,能够满足我们日常使用需求的属性字段。

此刻,我突然想到,objectCLass 就可以类比为数据库中提前约定设计好的表字段,只不过 openLDAP 已经默认集成了许多固定的模板,我们只需要选择其中的模板进行应用即可。

使用命令行参数创建用户属性方式如下:

# 创建一个用户 zhangsan
cat << EOF | ldapadd -x -D cn=admin,dc=eryajf,dc=net -w 123456
dn: uid=zhangsan,ou=people,dc=eryajf,dc=net
objectClass: inetOrgPerson
uid: zhangsan
cn: zhangsan
sn: zhang
displayName: 张三
userPassword: zhangsan
mobile: 15638888888
mail: zhangsan@eryajf.net
postalAddress: Hangzhou
businessCategory: 运维部
departmentNumber: 10
description: 测试用户
employeeNumber: 001
givenName: zhangsan
EOF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

在 go-ldap-admin 管理后台创建的用户,则与如上命令创建的效果一致。

# 分组

在 go-ldap-admin 项目中,创建一个分组条目使用的方式如下:

// Add 添加资源
func (x GroupService) Add(g *model.Group) error {
	if g.Remark == "" {
		g.Remark = g.GroupName
	}
	add := ldap.NewAddRequest(g.GroupDN, nil)
	if g.GroupType == "ou" {
		add.Attribute("objectClass", []string{"organizationalUnit", "top"})
	}
	if g.GroupType == "cn" {
		add.Attribute("objectClass", []string{"groupOfUniqueNames", "top"})
		add.Attribute("uniqueMember", []string{config.Conf.Ldap.AdminDN})
	}
	add.Attribute(g.GroupType, []string{g.GroupName})
	add.Attribute("description", []string{g.Remark})
	return common.LDAP.Add(add)
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

此处可以看到分组分了两类:organizationalUnitgroupOfUniqueNames

# top

其中的 top是一个顶级的属性,我们先来看下它的定义。

访问:http://localhost:8091/cmd.php?cmd=schema&server_id=1&view=objectclasses&viewvalue=top (opens new window)

因为 top 的必须项是一个属性,而我们创建的用户与分组都会附带对应的属性,因此这里的 top 事实上可以忽略,亦即不带。

# organizationalUnit

访问:http://localhost:8091/cmd.php?cmd=schema&server_id=1&view=objectclasses&viewvalue=organizationalUnit (opens new window)

organizationalUnit 必须项为 ou,我们从基础概念中知道,ou 是一个组织单位,组织单位可以包含其他各种对象(包括其他组织单元)。

所以这里 ou 的意义在于作为一个分组目录树的顶级组织,而非作为包含用户的实际分组。在 go-ldap-admin 的推荐用法中也是如此。

通过命令行创建一个organizationalUnit属性的条目:

cat << EOF | ldapadd -x -D "cn=admin,dc=eryajf,dc=net" -w 123456
dn: ou=group,dc=eryajf,dc=net
objectClass: organizationalUnit
ou: group
description: 分组的组织
EOF

1
2
3
4
5
6

# groupOfUniqueNames

访问:http://localhost:8091/cmd.php?cmd=schema&server_id=1&view=objectclasses&viewvalue=groupOfUniqueNames (opens new window)

可以看到必须项属性为 cn,亦即此项 objectCLass 创建时必须包含属性 cn。

另外一项必须项为:uniqueMember。

访问:http://localhost:8091/cmd.php?cmd=schema&server_id=1&view=attributes&viewvalue=uniquemember (opens new window)

该属性代表用户在分组中的一个条目。

通过命令行创建一个groupOfUniqueNames属性的条目:

cat << EOF | ldapadd -x -D "cn=admin,dc=eryajf,dc=net" -w 123456
dn: cn=yunweibu,ou=group,dc=eryajf,dc=net
objectClass: groupOfUniqueNames
cn: yunweibu
description: 运维部
uniqueMember: cn=admin,dc=eryajf,dc=net
EOF

1
2
3
4
5
6
7

需要注意对应的属性以及字段,其中必填项如果没有,执行命令则会报错。

因为 go-ldap-admin 后台创建分组的时候,并没有指定对应用户,所以创建的时候默认把 admin 用户放到分组内,以避免报错。


以上就是我对 objectCLass 的理解,希望你通过这篇文章的引导,能够大概掌握这一概念在 openLDAP 中的意义,并能够熟练应用它。

注意文中各种属性链接的规律,平时如果遇到不解的属性,可以在 phpLDAPadmin 中进行查询,这是本文最希望教给你的方法。