openLDAP入门系列笔记第二篇--简单认识objectCLass以及常见应用
本文我们来认识理解一个很重要的概念: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)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
此处可以看到开头声明的 objectCLass 为:inetOrgPerson
。
那么接下来,我们访问这个链接来查看该属性的具体含义。
通过这张图,我们能够更加清晰地理解 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
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)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
此处可以看到分组分了两类:organizationalUnit
和 groupOfUniqueNames
。
# top
其中的 top
是一个顶级的属性,我们先来看下它的定义。
因为 top 的必须项是一个属性,而我们创建的用户与分组都会附带对应的属性,因此这里的 top 事实上可以忽略,亦即不带。
# organizationalUnit
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
2
3
4
5
6
# groupOfUniqueNames
可以看到必须项属性为 cn,亦即此项 objectCLass 创建时必须包含属性 cn。
另外一项必须项为:uniqueMember。
该属性代表用户在分组中的一个条目。
通过命令行创建一个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
2
3
4
5
6
7
需要注意对应的属性以及字段,其中必填项如果没有,执行命令则会报错。
因为 go-ldap-admin 后台创建分组的时候,并没有指定对应用户,所以创建的时候默认把 admin 用户放到分组内,以避免报错。
以上就是我对 objectCLass 的理解,希望你通过这篇文章的引导,能够大概掌握这一概念在 openLDAP 中的意义,并能够熟练应用它。
注意文中各种属性链接的规律,平时如果遇到不解的属性,可以在 phpLDAPadmin 中进行查询,这是本文最希望教给你的方法。