身份系统迁移是 IAM
工程中最特殊的操作——它不像数据库迁移那样有标准的
pg_dump + pg_restore
路径。身份数据(尤其是密码和 MFA
凭据)的不可导出性使得迁移变成数学上的不可逆操作:你可以在数据层面迁移用户记录,但无法把
Keycloak 的 bcrypt 密码哈希转换成 Auth0
的格式并验证,也无法把 Auth0 的 TOTP 种子导入 Keycloak。
本文不仅是迁移方案指南——更是迁移风险的工程控制方法论。
一、为什么身份系统迁移比其他系统迁移难
| 数据类型 |
可迁移性 |
原因 |
| 用户档案(email、name、profile) |
容易 |
纯数据,API 导出即可 |
| 密码 |
不可直接迁移 |
哈希是单向的——且哈希算法和参数(bcrypt rounds、salt
格式)在不同系统间不兼容 |
| TOTP 种子 |
理论可迁移但通常不导出 |
种子在 IdP 内部加密存储,没有标准导出 API |
| WebAuthn / Passkey credential |
不可迁移 |
credential 绑定了 RP ID——换 IdP = 换 RP ID(域名) |
| OAuth Client 配置 |
可迁移(手动重建或脚本导入) |
纯配置数据 |
| 用户-角色关系 |
可迁移 |
角色定义可能不同,需要映射 |
| 现有 Session / Token |
不可迁移 |
Session 和 Token 由旧 IdP 签发,新 IdP 无法识别 |
核心结论:身份系统迁移的本质是让用户在有限的中断窗口内重新建立与新
IdP
的信任关系。你迁移的是用户档案和配置,不能迁移的是凭据和会话。
二、密码哈希桥接
密码的迁移是技术难度最高的环节。不能让所有用户重置密码(大量用户流失),不能保存明文密码,也不能简单地复制哈希值。
2.1
方案一:在线桥接(推荐)
用户首次在新 IdP 登录时:
sequenceDiagram
participant User as 用户
participant NewIdP as 新 IdP
participant Bridge as 桥接服务
participant OldIdP as 旧 IdP
User->>NewIdP: 1. 登录 (email + password)
NewIdP->>NewIdP: 2. 查本地——找不到用户哈希
NewIdP->>Bridge: 3. 请求密码验证
Bridge->>OldIdP: 4. 用旧 IdP 的 API 或加密通道发送密码
OldIdP->>Bridge: 5. 验证成功/失败
alt 验证成功
Bridge->>NewIdP: 6a. 通知"密码正确"
NewIdP->>NewIdP: 7a. 使用新哈希算法计算哈希,存入新 IdP
NewIdP->>User: 8a. 登录成功
else 验证失败
Bridge->>NewIdP: 6b. 通知"密码错误"
NewIdP->>User: 7b. 拒绝登录
end
关键安全要求: -
桥接服务不能记录明文密码——它只是转发验证请求的代理。
-
验证成功后,桥接服务应立即丢弃密码——用户下次登录时不需要桥接,因为新
IdP 已经有了新格式的哈希。 - 桥接服务和旧 IdP
之间的通信必须通过内部网络或 mTLS。 -
桥接服务的访问日志必须记录每次密码验证请求——这是合规审计的高敏感数据。
2.2
方案二:批量哈希重计算
如果旧 IdP 支持导出哈希值,可以用以下流水线批量迁移:
- 从旧 IdP 导出用户 ID + bcrypt hash(base64)。
- 在安全隔离的计算环境中,用迁移脚本重新计算——不是”重新哈希”(做不到),而是用相同的哈希格式和参数创建新
IdP 可读的记录。
- 在维护窗口中导入新 IdP。
约束:这只在旧 IdP 和新 IdP
使用相同或兼容的哈希算法时才可行。如果旧 IdP 用 bcrypt(\(2a\), rounds=12),新 IdP 用
Argon2id,哈希格式不兼容——无法批量迁移。
2.3
方案三:强制重置(最差选择,但有时必须)
发邮件通知所有用户”系统升级,请重置密码”。这会造成 15-30%
的用户流失(取决于用户基数和邮箱打开率),但有时的确是唯一选择——如从入侵事件中恢复时,不能信任旧系统的密码哈希未被泄露。
三、MFA 的迁移编排
MFA 凭据(TOTP 种子、WebAuthn credential、SMS
电话号码)比密码更难迁移。迁移 MFA
的策略是引导用户重新注册,而不是尝试迁移凭据。
编排流程:
- 通知阶段:在迁移日期前 2
周发邮件和应用内通知——“请在 X 日后重新设置
MFA”。解释原因(系统升级)。
- 宽限期:迁移后的 7 天内,旧 MFA
豁免——用户密码登录后直接进入,不要求
MFA。这一步是为了防止用户因”没收到通知、不会重新设置
MFA”而无法登录。
- 进度跟踪:在应用内显式提示”你还没有设置新的
MFA——安全保护降低中,设置只需 2 分钟”。
- 强制截止:宽限期(如 14 天)后,未设置
MFA 的用户强制设置——登录后必须先完成 MFA
注册,才能使用应用。
- SMS 后备:在整个迁移期间保持 SMS
作为后备第二因素——用户的手机号是从旧系统导出的,不需要用户重新设置。
四、灰度切流与 Session
连续性
4.1 灰度切流
迁移 1000
万用户的认证不能一次性切换——按百分比或按用户群灰度:
第 1 天: 新 IdP 处理 1% 流量(内部团队)
→ 观察: 登录成功率、延迟、错误类型
第 2 天: 10%
第 3 天: 30% (稳定 → 继续)
第 5 天: 100%
切流的手段: - DNS
权重切换:在反向代理(Nginx/Envoy)层按 Cookie
中的用户 ID 哈希做分流。用户 A 的哈希值落在
0-10%,被路由到新
IdP。这保证了同一用户不会因为”每次请求被不同的负载均衡器分配”而有时走新有时走旧。
-
应用层开关:在登录入口判断用户的迁移标记(如
user.migration_phase = 'new'),决定调用旧 IdP
还是新 IdP。
4.2 Session 连续性
迁移期间,已登录用户的 Session 不受影响——Session
有效性由签发它的 IdP 的 Token 有效期决定。
但 Refresh Token Rotation(第
07 篇)在迁移期间会出问题:用户在旧 IdP 有 Refresh
Token,但迁移后第一次刷新发现”旧 IdP
不管用了”——因为切流规则已经被路由到新 IdP。
解决方案:在迁移期间的切流层中,Refresh Token
请求始终路由到签发它的 IdP(通过
azp 或 token 内的 issuer
字段推断),而不是按切流权重路由。这需要切流代理理解 OAuth
Token 的 issuer 信息。
五、身份安全事故的应急响应
IAM 系统的安全事件有不同于基础设施事故的响应模式。
5.1 事故分类
| 事故类型 |
示例 |
首要响应 |
| 令牌/签名密钥泄露 |
HMAC secret 被公开在 GitHub repo 中 |
立即密钥轮换,所有现有 token 失效 |
| 用户凭据泄露(数据库漏扫) |
用户密码哈希 + MFA 种子被外泄 |
强制所有用户重置密码 + 重新注册 MFA |
| 特权账号滥用 |
管理员创建后门账号,API 异常调用 |
禁用特权账号,启动法务审计 |
| 身份平台宕机/降级 |
IdP 不可用,无法登录 |
启动 break-glass 流程 |
5.2 Break-Glass 流程
当 IdP
完全不可用时,需要一条”不能从大门进去,就爬窗户”的后备通路:
- Break-Glass 账号:预置 3-5
个高度受控的”紧急恢复账号”——密码分段保管(如 Shamir’s Secret
Sharing 分配给 5 人,任意 3 人组合可解锁)。
- Break-Glass
日志:每次使用紧急账号后,自动触发最高级别的告警,所有安全团队成员收到通知,并要求在
1 小时内完成事后审核。
- 降级认证模式:如果 OIDC/OAuth
全面不可用,启动降级模式——本地密码 verify +
管理员人工审批登录(如通过内部 ChatOps 工具)。
工程底线:Break-Glass
流程必须在系统正常时就设计好并测试过。你不能在火灾中设计消防通道。
5.3 事故事后改进清单
每次身份安全事故后的标准复盘清单:
- 受影响用户数量和时间窗口:哪些用户在什么时间段内暴露?
- 凭据失效范围:哪些 Token
/ Session / API Key / MFA 种子需要失效?
- 攻击路径分析:攻击者是从哪一层(认证/授权/令牌/平台)进来的?
- 检测延迟:从事件发生到被发现,间隔多久?为什么?
- 系统加固:防止同类攻击再犯——是配置错误?代码漏洞?社会工程?
六、小结
身份系统迁移和事故响应是 IAM
工程中”检验所有理论”的时刻——你设计的所有令牌机制、MFA
策略、审计日志和备份流程,都要在这个时刻被真实考验。
关键原则: 1.
密码哈希桥接是第一优先级的技术难题——在线桥接是最安全的方案。
2. MFA 迁移通过”宽限期 + 引导 +
强制”的编排完成,不是技术迁移。 3. Session
连续性通过切流代理的 issuer-aware 路由保持。 4. Break-Glass
流程必须在正常时设计、测试、文档化——不能在事故中临时拼凑。
上一篇:PAM、IGA
与审计合规
系列结束。返回 IAM 系列首页 查看完整目录。
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
2026-06-14 · architecture / security
SSO 只解决认证,SCIM 解决账号的生命周期管理。但 SCIM 2.0 的实现远不是调几个 REST API 那么简单:User/Group schema 的映射、Delta vs Full sync 的同步策略、Patch 操作语义,每个环节都有坑。本文从账号生命周期的四个关键事件出发,拆解 SCIM 2.0 的核心协议、同步模式、Schema 扩展,以及与企业 IdP(Azure AD、Okta)对接的实际工程经验。
2026-06-13 · architecture / security
从 2020 年 SolarWinds 到 2024 年 Okta 支持系统泄露,身份基础设施的安全失败反复证明一件事:IAM 不是 IT 支撑系统,而是安全架构的承重墙。本文建立现代 IAM 的全景地图——从认证协议、令牌体系、权限模型到身份治理与平台选型,给出 5 个贯穿全系列的核心问题。
2026-06-13 · architecture / security
OIDC 是当下企业 SSO 的事实标准,但大多数实现只用了它 20% 的规范。本文从 OIDC 核心规范出发,拆解 Authorization Code Flow + PKCE 的完整交互、ID Token 的验证规则、Discovery 与 Dynamic Registration 的互操作性机制,以及 RP-Initiated Logout 和 Session Management 的工程实现细节。
2026-06-13 · architecture / security
OAuth 2.1 不是新协议,而是对 OAuth 2.0 的安全加固:废除 Implicit Grant 和 Resource Owner Password Grant,强制 PKCE 用于所有使用授权码模式的客户端,要求精确 redirect_uri 比对。本文从 PKCE 的密码学动机出发,拆解 OAuth 2.1 的授权码流程完整交互、Refresh Token 轮换与发送者约束、DPoP 令牌绑定,以及 DCR (Dynamic Client Registration) 和 RAR (Rich Authorization Requests) 的实际应用。