LDAP 认证入门
1. 一句话简介
LDAP(Lightweight Directory Access Protocol,轻量级目录访问协议,RFC 4511)是访问和分发目录信息的标准协议。它以树形结构(DIT,目录信息树)组织数据,每条记录称为一个条目(Entry),由 DN(Distinguished Name)唯一标识,并通过 ObjectClass 定义其允许携带的属性(Attribute)。LDAP 是存储"身份与组织"信息的行业事实标准,OpenLDAP 和 Active Directory 是最常见的两种服务器实现。
在企业内部,用户账号通常是统一存放在 LDAP 目录中的,本模块用 spring-boot-starter-data-ldap 演示如何对接 OpenLDAP:通过 @Entry 注解把 Java 对象映射到 LDAP 条目(类似 JPA 的 @Entity),通过 CrudRepository 完成增删改查,并以"按用户名取回用户 + LdapUtils 校验 SSHA/SHA 密码"的登录认证为实战示例。核心解决的是:让应用能借助统一的身份目录做用户查询与认证,而不是在每个系统里各自维护一套账号。
2. 什么时候使用
✅ 适用场景
- 已有统一身份目录的企业环境:公司运营阶段通常已有 OpenLDAP 或 Active Directory,应用系统需要直接对接它完成用户认证与信息读取,LDAP 是天然选择。
- 多系统共享同一套账号与组织架构:多个应用都需要读取"员工是谁、属于哪个部门"这类信息时,集中存储在 LDAP 一处,各系统通过协议访问,避免各建一套账号表导致的数据不一致。
- 需要与 SSO / Kerberos / AD 生态集成:密码集中管理、单点登录、域控环境登录等场景,LDAP 协议与这些基础设施天然集成。
- 以读为主、查询频繁的身份信息访问:LDAP 是读优化存储,查询(尤其按 uid、cn 等索引属性检索)非常快,适合高频的用户信息读取。
- 追求低开发成本地接入 LDAP:本模块展示用
CrudRepository一个接口即可获得 save/findAll/findByUid 等能力,几乎零样板代码。
❌ 不适用 / 需谨慎
- 业务型、写密集型的数据存储:LDAP 写入性能差,Attribute 模型也不适合表达复杂业务关系,业务数据应放关系型数据库(本模块的
PersonServiceImpl已有"密码不应返回前端"等实践,说明它本质定位是身份目录)。 - 轻量单应用、无共享诉求的项目:如果只有单个应用、几十个用户,引入并运维一个 LDAP 服务器反而增加复杂度,直接用 Spring Security 配合数据库存用户更简单。
- 复杂查询与报表分析:LDAP 只支持受限的过滤器表达式,不支持 JOIN、聚合、范围排序,复杂查询应交给数据库。
- 对自建密码存储方案有强需求时:LDAP 密码以
{SSHA}/{SHA}等哈希形式存储且由目录管理,若需要自定义加解密、多因素等能力,需要评估目录是否满足。
3. 常见业务场景
企业员工统一登录认证:员工凭用户名 + 密码登录各类内部系统。本模块的 PersonServiceImpl.login() 演示了该核心流程——按 uid 从 LDAP 查出用户,用 LdapUtils.verify() 将用户输入与 LDAP 中 {SSHA}/{SHA} 哈希后的密码比对,验证失败统一提示"用户名或密码错误"(不区分用户不存在与密码错误,防用户名枚举)。由于账号集中在目录中,某员工离职删除一次,所有系统同步失效。
统一组织架构与人员信息查询:HR 系统、通讯录、审批流等都需要起人、部门、岗位、邮箱、电话等信息。@Entry(base = "ou=people", objectClasses = {"posixAccount", "inetOrgPerson", "top"}) 把一条员工记录建模成含 cn 姓名、sn 姓氏、mail、title 职位、departmentNumber 部门等的条目,各系统统一读取,信息一次维护多处共享。
账号生命周期集中管理:新员工入职、调岗、离职的账号创建/更新/删除都集中到 LDAP。模块中的 save()(LDAP ADD/MODIFY)与 delete()(LDAP DELETE)即对应此类操作,运维人员或专门的账号系统直接对目录操作即可。
系统间身份对接的基础设施:为后续接入单点登录、Kerberos 认证、AD 域控等做准备。目录以标准 LDAP 协议对外提供身份能力,上层应用无需关心底层目录实现,为面向未来的企业身份体系提供统一入口。
只读的第一方用户身份读取:无用户中心的中小型应用需要关联到已有企业人员体系时,通过 LDAP 只读查询用户属性(姓名、邮箱、部门)完成身份落地,避免在业务库重复存储一份人员数据。
4. 同类技术对比
| 维度 | LDAP(OpenLDAP / AD) | 关系型数据库存用户(MySQL 等) | 专有身份服务(Keycloak / Auth0 等) | 应用内账号框架(Spring Security + 内置账号) |
|---|---|---|---|---|
| 数据模型 | 树形目录(Entry/DN/Attribute) | 二维表,可 JOIN | 面向身份的抽象模型 | 表结构(users / roles) |
| 读写特性 | 读优化,读快写慢 | 读写均衡 | 读快写快(内置持久化) | 取决于底层存储 |
| 查询能力 | 仅过滤器表达式,无 JOIN/聚合 | 强大 SQL,支持复杂查询 | 面向提供 API 的身份查询 | 简单,通常按用户名 |
| 企业标准集成 | 与 AD / Kerberos / SSO 天然集成 | 无统一标准,需自建 | 提供 SP/IdP 协议对接(SAML/OIDC) | 无,需自行对接 |
| 开发成本 | 低(本模块一个 CrudRepository) |
中(需建表 + 权限框架) | 中(搭建 + 配置协议) | 低(遵循框架约定) |
| 运维成本 | 中(需独立部署目录服务) | 低(复用已有数据库) | 高(独立服务 + 高可用) | 极低(随应用部署) |
| 学习成本 | 中(DN/ObjectClass/过滤器等新概念) | 低(SQL 熟悉) | 中 | 低 |
| 适用规模 | 大(跨系统统一身份) | 中小(单个应用) | 大(企业级统一身份平台) | 小(单应用) |
选型建议:如果目标是"企业内部多系统共享并集中管理用户身份、且已有或愿意部署 OpenLDAP/AD",选 LDAP,它能提供标准协议、与 SSO/Kerberos 的天然集成和统一目录。若只是单个应用、几十到几百账号、无跨系统共享诉求,直接用 Spring Security + 数据库存用户更轻量。若企业需要完整的身份管理平台(OAuth、组管理、登录页、多实例高可用),选 Keycloak 等专有身份服务。复杂的业务关系数据与报表分析则始终交由关系型数据库,LDAP 只负责身份目录这一层。