4. LDAP 目录结构设计:组织单元、用户条目与组条目 Schema

LDAP 目录是认证授权平台的身份数据核心。本章围绕 组织单元 (OU)、用户条目 (inetOrgPerson) 和 组条目 (groupOfUniqueNames) 三类核心对象,定义其 Schema 结构与层级关系。设计目标:支撑 Redis 缓存层的高效查询,同时保持 LDAP 原生目录的灵活性与可扩展性。

4.1 目录树顶层结构

采用 扁平化 + 按职能分区 的 OU 设计,避免过深嵌套导致查询性能下降。顶层 OU 划分如下:

OU 名称 DN 示例 用途
ou=people ou=people,dc=example,dc=com 存放所有用户条目 (inetOrgPerson)
ou=groups ou=groups,dc=example,dc=com 存放所有组条目 (groupOfUniqueNames)
ou=apps ou=apps,dc=example,dc=com 存放应用服务账号 (inetOrgPerson)
ou=roles ou=roles,dc=example,dc=com 存放角色定义 (groupOfUniqueNames)
设计原则: 每个 OU 对应一类实体,避免混合存放。这样在 Redis 缓存键设计时,可以直接以 OU 为前缀做批量失效,提升缓存管理效率。
LDAP 目录树顶层 OU 结构 dc=example,dc=com ou=people ou=groups ou=apps ou=roles 目录树设计要点 • 每个 OU 只存放一类实体,避免混合 • 深度不超过 3 层,保证查询性能 • OU 名称使用英文复数,保持命名一致性 • 应用账号与自然人账号分离,便于审计 • 角色组独立 OU,支持细粒度授权

4.2 用户条目 Schema:inetOrgPerson

用户条目使用 inetOrgPerson 对象类,它是 LDAP 标准中描述互联网用户的扩展类,继承自 organizationalPerson 和 person。我们选取以下核心属性用于认证授权场景:

属性名 类型 是否必填 说明
uid Directory String 是 用户登录名,RDN 属性
cn Directory String 是 用户全名
sn Directory String 是 用户姓氏
userPassword Octet String 是 密码哈希值 (SSHA/BCrypt)
mail Directory String 否 用户邮箱
telephoneNumber Telephone Number 否 用户电话
employeeID Directory String 否 员工工号,用于关联业务系统
departmentNumber Directory String 否 部门编号,用于组织过滤
description Directory String 否 用户备注
LDIF 示例: 创建一个用户条目,RDN 使用 uid,确保唯一性。
dn: uid=zhangsan,ou=people,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
uid: zhangsan
cn: 张三
sn: 张
userPassword: {SSHA}xxxxxxxxxxxxxxxxxxxx
mail: zhangsan@example.com
telephoneNumber: 13800138000
employeeID: EMP2024001
departmentNumber: D001
description: 研发部高级工程师

4.3 组条目 Schema:groupOfUniqueNames

组条目使用 groupOfUniqueNames 对象类,它通过 uniqueMember 属性存储组成员 DN,支持多值。相比 groupOfNames,groupOfUniqueNames 强制成员 DN 唯一,避免重复添加。

属性名 类型 是否必填 说明
cn Directory String 是 组名称,RDN 属性
uniqueMember DN 是 组成员 DN,可多值
description Directory String 否 组描述
businessCategory Directory String 否 组类别 (如: devops, security, admin)
性能注意: 当组成员超过 500 时,uniqueMember 的多值查询会变慢。建议对超大组使用嵌套组结构,或通过 Redis 缓存组成员列表。
dn: cn=devops-team,ou=groups,dc=example,dc=com
objectClass: groupOfUniqueNames
objectClass: top
cn: devops-team
uniqueMember: uid=zhangsan,ou=people,dc=example,dc=com
uniqueMember: uid=lisi,ou=people,dc=example,dc=com
uniqueMember: uid=wangwu,ou=people,dc=example,dc=com
description: DevOps 工程团队
businessCategory: devops

4.4 角色组与权限映射

在 ou=roles 下存放角色定义,每个角色也是一个 groupOfUniqueNames 条目,但 uniqueMember 指向的是 ou=groups 下的组 DN,形成 角色 → 组 → 用户 的间接映射。这种设计支持 RBAC 模型,且角色变更时只需修改角色条目,不影响用户条目。

角色 DN 成员组 DN 权限范围
cn=admin-role,ou=roles,... cn=admin-group,ou=groups,... 系统管理权限
cn=dev-role,ou=roles,... cn=devops-team,ou=groups,... 开发环境读写权限
cn=audit-role,ou=roles,... cn=audit-group,ou=groups,... 审计日志只读权限
RBAC 角色-组-用户映射关系 cn=admin-role,ou=roles cn=admin-group,ou=groups uid=zhangsan uid=lisi uid=wangwu 映射规则 角色 uniqueMember → 组 DN;组 uniqueMember → 用户 DN。角色变更不影响用户条目。

4.5 Schema 设计检查清单

  • 唯一性约束: uid 在 ou=people 下必须全局唯一,建议在 LDAP 服务端配置 uid 唯一性插件。
  • 密码策略: userPassword 存储哈希值,推荐 SSHA 或 BCrypt;禁止明文存储。
  • 索引优化: 为 uid、mail、uniqueMember 创建索引,加速认证和组查询。
  • 对象类继承: 每个条目必须包含 top 对象类,并按照 inetOrgPerson 或 groupOfUniqueNames 的继承链完整声明。
  • DN 长度控制: 避免 DN 过长(超过 255 字符),否则影响 LDAP 查询性能和 Redis 缓存键长度。
  • 审计字段: 建议扩展 inetOrgPerson 增加 createTimestamp 和 modifyTimestamp 操作属性,用于缓存同步校验。
缓存集成提示: 在 Redis 中缓存用户条目时,使用 uid 作为键的一部分(如 ldap:user:{uid}),缓存组条目时使用 cn(如 ldap:group:{cn})。当 LDAP 条目发生修改时,通过监听 modifyTimestamp 变化来失效对应缓存。