认证服务-企业内部-ldap

上层

基于企业组织关系进行人员认证,开箱即用的微服务

底层存储

默认是嵌入式数据库,最终是写到文件上
支持多种backend实现
对于用户的企业组织关系是通过目录信息树元信息体现的

  • 最小存储单元是条目
    一个条目就是一个对象
    比如一个用户条目对象,一个组织条目对象
  • DN
    DN定义了一个条目对象的【组织层级关系和主键标识】

一个条目对象通过DN字段来唯一标识
DN字段存储了【该条目的目录信息树】信息,由多个rdn属性组成,以路径的方式显示定义了从左到右的目录层级关系,右侧的rdn是左侧的父级目录,最右侧的rdn即该条目的目录信息树的根节点!

DN的组成部分:约定俗成的属性
首先,CN、OU、DC 这些是 LDAP 协议标准中定义的一些属性类型,它们有约定的含义:
CN :通用名称,最常见的是用于用户(uid)的名称,例如:cn=John
OU:组织单元。用于在组织内创建分支或部门,是构建目录树的主要方式。例如:ou=People, ou=Groups, ou=Engineering, ou=San Francisco
DC:域组件,目录树的根节点,例如域名 example.com 会转化为 dc=example, dc=com
为什么 DC 作为根成为主流?
与 DNS 天然集成:公司域名(如 company.com)是全球唯一的,这自然保证了 LDAP 目录命名空间的唯一性
cn和uid的关系
cn和uid是父子级吗? 不是,它们是平行的、可供选择的属性类型
uid 是用户的登录名,通常一生不变。即使用户从“Alice Smith”改名为“Alice Jones”,她的 cn 属性可以变,但她的唯一标识 uid=alice 和整个DN保持不变

目录树结构:需要提前设计和创建
虽然属性类型是标准的,但如何组合它们来形成您公司的目录信息树,则完全需要管理员手动设计
比如一个三级目录树结构
根节点:dc=acme, dc=com (基于公司域名)
一级OU:将用户(People)、组(Groups)和部门(Engineering, Sales)分开
用户DN:cn=Alice Smith, ou= Engineering, dc=acme, dc=com
但不需要像在MySQL中那样,先创建一张包含cn、ou、dc字段的“表结构”,LDAP的目录树结构是通过直接创建条目(Entry)本身来隐式定义的

如何查看ldap服务最全的目录信息树结构
1)先查询根目录
ldapsearch -x -H ldap://your.ldap.server:389 -b "" -s base "(objectclass=)" namingContexts
在这个输出中
【namingContexts】: dc=example,dc=com 就是您需要的主要 Base DN
2)再展开根目录
ldapsearch -x -H ldap://your.ldap.server:389 -b "dc=example,dc=com" -s sub "(objectclass=
)"
需要指定admin账号才能查询目录到情况
ldapsearch -x -H ldap://your.ldap.server:389
-D "cn=admin,dc=example,dc=com" -W \ // 指定具有搜索权限的账号
-W \ // 待会手动输入密码
-b "dc=example,dc=com" \ // 指定Base DN
-s sub "(objectClass=*)" dn // 搜索结果只展示dn

-s base查询当前目录的节点
-s one查询当前目录的下一级目录节点
-s sub查询当前目录的递归所有子目录节点

3)分页查询
可以使用 -z 参数来限制每次返回的条目数,
ldapsearch -x -b "dc=example,dc=com" -s sub "(objectclass=*)" -z 100

为用户条目设置密码
ldappasswd -x -H ldap://10.20.47.231:10389
-D "uid=admin,o=emr" -W -s "123456" "uid=zhangyong,ou=people,o=emr"

验证密码是否设置成功
ldapwhoami -x -H ldap://10.20.47.231:10389
-D "uid=zhangyong,ou=people,o=emr"
-w "123456"

  • objectClass
    objectClass定义了【一个条目对象所拥有的所有属性 和 条目类型】

1)定义了条目类型
虽然 objectClass 主要用于定义条目应该具备哪些属性
但它间接地帮助区分条目类型,这是因为【不同类型的条目】会选择【不同的 objectClass】 来表达
用户条目
objectClass: inetOrgPerson, person,organizationalPerson
组条目
objectClass: posixGroup(linux ldap)
groupOfNames(windows ldap)
组织单元条目
objectClass: organizationalUnit,organizationalRole

2)一个条目对象所拥有的所有属性
定义了该条目对象【所拥有的所有属性,不包含用户的组织层级关系】!!!

objectclass字段存储了多个类,即通过这些类间接指定了条目对象所拥有的属性
具体每个类的定义需要提前在ldap的配置文件中定义
常见的类有person,inetOrgPerson,groupOfNames,organizationalUnit

// 查询所有定义的对象类,会返回大量数据
ldapsearch -H ldap://your-ldap-server -x -s base -b "cn=subschema" objectclasses
// 更精确地查询单个对象类的定义,例如 inetOrgPerson
ldapsearch -H ldap://your-ldap-server -x -s base -b "cn=subschema" "(objectclasses=inetOrgPerson)"

  • 组条目
    如何表示组与成员用户关系
    1)通过dn中包含的组织层级关系
    2)通过组条目对象的memberUid属性

linux中常见组条目对象定义如下
通过memberUid属性指定组成员,组成员通过uid唯一标识
dn: cn=developers,ou=groups,dc=example,dc=com
objectClass: top
objectClass: posixGroup
cn: developers // 组的名称
gidNumber: 1001 // 组的id
// memberUid属性指定了属于该组的用户的 UID
memberUid: user1
memberUid: user2

windows中常见组条目对象定义如下
通过member 属性指定组成员,组成员通过dn唯一标识
dn: cn=developers,ou=groups,dc=example,dc=com
objectClass: top
objectClass: groupOfNames
cn: developers // 组的名称
description: Developers group for project X。// 组的描述
// member 属性指定了组内所包含的所有成员的DN
member: uid=jdoe,ou=users,dc=example,dc=com
member: uid=asmith,ou=users,dc=example,dc=com

查询 posixGroup 类型的组(常见于linux ldap)
ldapsearch -H ldap://10.20.47.231:10389 -x -b "o=emr" -s sub "(objectClass=posixGroup)"
查询特定组的成员
ldapsearch -H ldap://10.20.47.231:10389 -x -b "ou=groups,o=emr" -s base "(objectClass=*)" memberUid

组合查询
通过一个查询语句查询某个用户,过滤条件是这个用户属于某个组
1)windows ldap中
Microsoft Active Directory为用户条目提供了独有的memberOf属性
表示该用户所属的组
(&(uid=jdoe)(memberOf=cn=admins,ou=groups,dc=example,dc=com) )
2)linux ldap中
利用posixAccount类型的用户条目,包含的 gidNumber属性:这表明用户的主组 ID
利用 uid 和 gidNumber 组合查询
( &(uid=jdoe)(gidNumber=1001) )

创建组条目
ldapadd -H ldap://10.20.47.231:10389 -x -D "uid=admin,o=emr" -W -f group.ldif

使用步骤

  • 上游数据源
    通常是从人事系统中导出公司组织与人员信息
    然后写入ldap服务

  • ldap生成数据
    如何插入/更新数据
    变更请求格式为ldif文件
    使用ldapmodify命令执行这个文件

如何实时更新数据
1)通过定时调度监控上游源变化执行ldapmodify命令
2)使用现成的三方工具
apachesyncope

  • 服务对外提供的接口
    ldap服务提供了基于ldap协议的接口,简化了数据更新/查询
    比如使用java的ldap库来进行rpc调用接口
  • 从ldap用数认证
    风险
    耦合问题:ldap挂了后,所有服务无法使用
    性能问题:每个请求都去查下ldap服务带来的性能消耗
    一致性问题:保持与最新ldap数据同步
    -》ldap原生支持变更日志机制
    OpenLDAP 有 accesslog 和 auditlog overlays,可以记录所有变更操作
    方案一:直接查询模式(不推荐)
    存在耦合问题
    存在性能问题
    方案二:缓存模式(最常用、最实用)
    将查询ldap服务的用户组织信息在应用微服务中缓存下来
    后续请求【直接从缓存】读取用户组织信息
    一致性问题:
    -》设置合理的过期时间
    监控到关键变更后及时【更新缓存】
  • 集成
    ldap服务地址
    管理员账号:拥有查询所有用户组织信息的权限
    搜索库:查询用户组织信息的底层存储
    搜索属性:使用用户的哪个字段进行查找用户是否存在
    传输协议
    特有的ldap协议
    原生就是一个公共服务
    提供单点登陆功能
    符合单一职责,完美等同于一个认证微服务!!!
    dolphin自带集成ldap
    3.3.1版本支持LDAPTLS/SSL
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容