Keycloak → LDAP sync via UserModelDelegate proxy in setEnabled() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Keycloak OpenLDAP PPolicy Status Mapper
将 OpenLDAP 的 pwdAccountLockedTime 属性映射为 Keycloak 的用户启用/禁用状态。
背景
OpenLDAP 使用 ppolicy overlay 管理密码策略,当账号被锁定时会设置 pwdAccountLockedTime 属性。Keycloak 默认无法识别该属性,导致 LDAP 中已锁定的用户在 Keycloak 中仍然显示为启用状态。
本 provider 通过自定义 LDAP Storage Mapper 解决这一问题。
工作原理
- LDAP 查询阶段 —
beforeLDAPQuery中将pwdAccountLockedTime加入返回属性,确保 LDAP 查询结果包含该字段 - 用户导入阶段 —
onImportUserFromLDAP中读取pwdAccountLockedTime的值:- 属性存在且非空 → 用户设置为
enabled = false - 属性不存在或为空 → 用户设置为
enabled = true
- 属性存在且非空 → 用户设置为
注意:OpenLDAP 管理员主动禁用账号时,
pwdAccountLockedTime通常被设为000001010000Z,该场景同样会被识别为锁定。
构建
mvn clean package
构建产物位于 providers/PwdLockToEnabledMapper/target/。
部署
- 将构建生成的 JAR 文件复制到 Keycloak 的 providers 目录:
cp providers/PwdLockToEnabledMapper/target/pwd-lock-to-enabled-mapper.jar \
<KEYCLOAK_HOME>/providers/
- 重启 Keycloak 或执行一次构建:
<KEYCLOAK_HOME>/bin/kc.sh build
配置
- 登录 Keycloak Admin Console
- 进入目标 Realm → User Federation → 选择已配置的 LDAP provider
- 在 Mappers 标签页点击 Add mapper
- 填写配置:
- Mapper Type:选择
OpenLDAP PPolicy Status Mapper - Name:自定义名称,如
pwdLockStatus
- Mapper Type:选择
- 保存
配置完成后,下次 LDAP 同步时将自动根据 pwdAccountLockedTime 更新用户启用状态。
项目结构
providers/PwdLockToEnabledMapper/
└── src/main/
├── java/com/example/keycloak/
│ ├── PwdLockToEnabledMapper.java # Mapper 实现
│ └── PwdLockToEnabledMapperFactory.java # Factory,provider ID: openldap-ppolicy-mapper
└── resources/META-INF/services/
└── org.keycloak.storage.ldap.mappers.LDAPStorageMapperFactory # SPI 注册
前提条件
- Keycloak 版本需支持
AbstractLDAPStorageMapper/AbstractLDAPStorageMapperFactoryAPI - OpenLDAP 需启用 ppolicy overlay
- LDAP 用户条目需包含
pwdAccountLockedTime属性(ppolicy overlay 自动管理)
限制
- 仅支持 LDAP → Keycloak 单向同步,Keycloak 中的禁用操作不会同步回 LDAP
pwdAccountLockedTime属性必须可被 Keycloak 的 LDAP 服务账号读取