IAM 认证协议选型:OAuth、OIDC、SAML、LDAP、SCIM | IDaaS Book
协议选型为什么重要
IAM 系统的核心任务是"把正确的身份信息,在正确的时机,以正确的方式,交给正确的应用"。而协议就是这条信息传递通道的语法和合同。
选错协议的代价不是"功能少了几个",而是:
| 问题类型 | 典型后果 | 实际案例 |
|---|---|---|
| 协议不匹配 | 用 OAuth 做认证,结果拿到 Access Token 却不知道用户是谁 | 早期很多开发者把 OAuth 2.0 当成"社交登录协议"用 |
| 过度设计 | 在内部管理面板里用 SAML,每个 SP 都要交换 XML 元数据 | 几十个内部工具维护 SAML metadata 的运维噩梦 |
| 协议混用 | OIDC + SAML 双栈但未统一会话管理,导致登出不同步 | 用户在一个应用登出,另一个应用会话依然有效 |
| 安全盲区 | PKCE 缺失、redirect_uri 未校验、state 参数未使用 | OAuth 授权码拦截、CSRF、Mix-Up Attack |
本章不重复 OAuth 2.0、OIDC、SAML 的协议细节——那些在 协议与标准部分有完整阐述。这里专注于决策:你面对一个具体场景时,该选哪个协议、为什么、不选其他协议的原因是什么。
一个容易被忽略的边界是:协议选型不能替代授权边界设计。用 OIDC 登录并不等于应用已经完成 API 授权;网关放行后,资源服务器仍需验证 Access Token 的 iss、aud、有效期和权限。以 IAM 网关为例,见
Keycloak + oauth2-proxy 的认证与后端校验边界。
五大协议的核心定位
在进入决策树之前,先理解每个协议在 IAM 体系中的核心角色——它们解决的是不同层面的问题:
graph TD
subgraph "IAM 协议体系"
AUTH_Z[授权<br/>OAuth 2.0] --> |构建于| AUTH_N[认证<br/>OpenID Connect]
AUTH_N --> |替代/互补| SAML[SAML 2.0<br/>企业 SSO]
DIR[LDAP<br/>目录查询] --> |用户源| AUTH_N
DIR --> |用户源| SAML
PROV[SCIM<br/>生命周期管理] --> |同步到| AUTH_N
PROV --> |同步到| SAML
end
style AUTH_Z fill:#e1f5fe
style AUTH_N fill:#c8e6c9
style SAML fill:#fff9c4
style DIR fill:#f3e5f5
style PROV fill:#ffe0b2
| 协议 | 核心问题 | 在 IAM 中的位置 | 数据格式 | 典型端口 |
|---|---|---|---|---|
| OAuth 2.0 | “我能做什么?(授权)” | 授权层——控制第三方应用对受保护资源的访问范围 | JSON | 通常 HTTPS |
| OpenID Connect (OIDC) | “你是谁?(认证)” | 认证层——OAuth 2.0 + 身份层,标准化用户身份传递 | JSON (JWT) | HTTPS |
| SAML 2.0 | “企业里的你是谁?(联邦认证)” | 身份联邦——跨组织/跨域传递用户身份断言 | XML | HTTPS / Redirect |
| LDAP | “用户信息在哪?(目录查询)” | 用户存储——身份数据的查询、验证和修改协议 | ASN.1 / LDIF | 389 / 636 |
| SCIM | “用户怎么创建/更新/删除?(生命周期)” | 用户供应——自动化用户帐号的 CRUD 生命周期管理 | JSON (REST) | HTTPS |
一句话判断:需要授权第三方访问资源 → OAuth 2.0;需要证明"我是谁" → OIDC 或 SAML;需要连企业 AD → LDAP;需要自动创建/删除用户 → SCIM;需要跨公司 SSO → SAML 或 OIDC Federation。
IAM 协议选型决策树
下面这个决策树覆盖了企业 IAM 中最常见的 10 种场景。从你的需求出发,沿着分支走到叶子节点,就是推荐协议。
graph TD
START["我需要什么?"] --> Q1{"需要授权第三方<br/>访问我在另一个服务上的资源?"}
Q1 -->|是| Q1A{"有用户在场吗?"}
Q1A -->|是| REC_OAuth_Code["OAuth 2.0 Authorization Code + PKCE<br/>同时可选 OIDC 获取用户身份"]
Q1A -->|否| Q1B{"是服务间通信?"}
Q1B -->|是| REC_OAuth_CC["OAuth 2.0 Client Credentials Grant"]
Q1B -->|否| Q1C{"是没有浏览器的设备?"}
Q1C -->|是| REC_OAuth_DC["OAuth 2.0 Device Code Grant"]
Q1C -->|否| REC_OAuth_Code["OAuth 2.0 Authorization Code + PKCE<br/>让授权服务器处理用户认证"]
Q1 -->|否| Q2{"需要跨组织 / 跨公司 SSO?"}
Q2 -->|是| Q2A{"对方是否支持 OIDC?"}
Q2A -->|是| REC_OIDC_FED["OIDC Federation<br/>或 OpenID Federation 1.0"]
Q2A -->|否/传统企业| Q2B{"需要 SAML?"}
Q2B -->|是| REC_SAML["SAML 2.0 SP-Initiated SSO"]
Q2B -->|否| REC_OIDC["OpenID Connect"]
Q2 -->|否| Q3{"应用类型?"}
Q3 -->|"现代 SPA / 移动 App / API"| REC_OIDC_SPA["OIDC + PKCE<br/>使用 Authorization Code Flow"]
Q3 -->|"传统 Web 应用<br/>/ .NET / Java EE"| Q3A{"技术栈偏好?"}
Q3A -->|"已有 SAML 基础设施<br/>或使用 AD FS"| REC_SAML2["SAML 2.0"]
Q3A -->|"现代化优先"| REC_OIDC_WEB["OIDC Authorization Code Flow"]
Q3 -->|"需要查询/验证 AD/LDAP"| REC_LDAP["LDAP / LDAPS<br/>可选 Keycloak User Federation 封装"]
Q3 -->|"需要自动化用户生命周期管理"| REC_SCIM["SCIM 2.0<br/>配合 IdP 的 SCIM 端点使用"]
style REC_OAuth_Code fill:#c8e6c9
style REC_OIDC fill:#c8e6c9
style REC_OIDC_SPA fill:#c8e6c9
style REC_OIDC_WEB fill:#c8e6c9
style REC_OIDC_FED fill:#c8e6c9
style REC_SAML fill:#fff9c4
style REC_SAML2 fill:#fff9c4
style REC_LDAP fill:#f3e5f5
style REC_SCIM fill:#ffe0b2
style REC_OAuth_CC fill:#e1f5fe
style REC_OAuth_DC fill:#e1f5fe
决策树使用说明:
- 从顶部"我需要什么"开始,诚实回答自己的需求
- 一个项目可能涉及多个分支——例如一个 SaaS 产品可能同时需要 OAuth 2.0(第三方集成)、OIDC(用户登录)、SCIM(企业客户自动同步用户)
- 没有“把用户密码交给客户端”的分支:RFC 9700 §2.4 要求不得使用 ROPC。遗留系统应迁移到 Authorization Code + PKCE,而不是把密码模式包装成“内部专用”。
十个典型场景的协议选型
场景 1:SaaS 产品需要支持企业客户 SSO 登录
需求:让使用 Okta / Entra ID / Google Workspace 的企业客户,用他们自己的帐号登录你的 SaaS。
| 考量 | 答案 |
|---|---|
| 推荐协议 | OIDC 为主,SAML 2.0 作为补充 |
| 为什么不是纯 SAML | 大多数现代 IdP 已支持 OIDC;OIDC 客户端实现简单、调试方便、JSON 可读性远好于 XML |
| 为什么还要 SAML | 传统企业(金融/政府)和 Microsoft AD FS 生态仍然主要使用 SAML——如果不支持 SAML,你就放弃了一批大客户 |
| 实现策略 | 新接入优先使用 OIDC;只有客户现有 IdP 或互操作要求明确需要 SAML 时,再纳入 SAML 兼容范围 |
实现时需要注意:Keycloak 可以同时作为 OIDC Provider 和 SAML IdP;Dex 只做 OIDC 到上游 IdP 的联邦代理,不原生支持 SAML。如果要用 SAML,Keycloak 比 Dex 更合适。
场景 2:内部工具统一登录(Grafana / Jenkins / Harbor / GitLab 等)
需求:公司内部 20-50 个 DevOps 工具需要单点登录。
| 考量 | 答案 |
|---|---|
| 推荐协议 | OIDC(几乎所有现代 DevOps 工具都支持 OIDC) |
| 配置方式 | oauth2-proxy 作为反向代理前置,或各工具原生 OIDC 集成 |
| 为什么不是 SAML | 配置成本高——每个工具的 SAML metadata 都要维护,内部环境没必要承受这个复杂度 |
| 特殊注意 | 一些老工具(如 Jenkins 旧版)可能需要 SAML 插件,考虑升级或替换 |
场景 3:移动 App 需要登录
需求:原生 iOS/Android App 的用户登录。
| 考量 | 答案 |
|---|---|
| 推荐协议 | OIDC Authorization Code + PKCE |
| 为什么 PKCE 必须 | 移动 App 无法安全保存 client_secret。PKCE 提供了等效的安全保障 |
| 推荐库 | AppAuth (iOS/Android),不要用 WebView 直接加载登录页 |
| 为什么不是 Implicit Grant | OAuth 2.1 已废弃 Implicit Grant——它在移动端的攻击面(token 可能被拦截、无法验证 redirect_uri)已被 PKCE + Authorization Code 替代 |
场景 4:微服务间 API 调用需要授权
需求:Service A 调用 Service B 的 API,两个服务都是内部系统,没有用户参与。
| 考量 | 答案 |
|---|---|
| 推荐协议 | OAuth 2.0 Client Credentials Grant |
| 实现方式 | 两个服务各有一个 client_id + client_secret,A 用它们向 IdP 换取 Access Token,然后带着 Token 调用 B |
| Token 传递 | 如果走 API Gateway,Gateway 完成 Token 校验和转发;如果是直连,B 自己校验 Token(Introspection 或本地 JWT 验证) |
| 为什么需要 OAuth 而不是简单的 API Key | Client Credentials 提供 token 过期、scope 限制、可撤销、审计日志——静态 API Key 做不到 |
场景 5:企业需要从 AD / LDAP 同步用户到 SaaS 平台
需求:企业有 AD 域控,需要在 SaaS 平台中自动创建/更新/禁用用户。
| 考量 | 答案 |
|---|---|
| 推荐协议 | SCIM 2.0(用于用户生命周期管理)+ LDAP(用于数据读取和认证) |
| 架构 | AD → LDAP 查询 → 同步工具/SCIM 网关 → SaaS 平台的 SCIM 端点 |
| 为什么不是直接暴露 LDAP | 暴露 LDAP 给互联网等于把目录服务暴露在攻击面下;SCIM 是 RESTful、有 Token 认证、支持过滤和分页 |
| 开源实现 | Keycloak 支持 LDAP User Federation(实时读取);Keycloak 26.7 起可在启用 SCIM Preview 后提供 SCIM Service Provider 端点,生产使用前要按当前版本文档确认 Preview 边界 |
场景 6:电商网站需要"用微信/Google/Apple 登录"
需求:C 端用户不想注册新帐号,想用已有社交帐号登录。
| 考量 | 答案 |
|---|---|
| 推荐协议 | OIDC(Google/Apple 已经支持 OIDC);微信使用的是变种 OAuth 2.0 |
| IDP 端配置 | 在 Keycloak Identity Provider 中添加 Google / Apple / 微信,它们会自动处理协议适配 |
| 帐号关联 | 确保处理"同一个邮箱可能来自不同社交平台"的情况——Keycloak 的 Account Linking 可以解决 |
场景 7:两家公司合并后,员工需要互相访问对方的内部系统
需求:A 公司和 B 公司合并,A 的员工需要用 A 的帐号访问 B 的内部系统。
| 考量 | 答案 |
|---|---|
| 推荐协议 | SAML 2.0(企业互信的传统方案)或 OIDC Federation(新方案) |
| 为什么 SAML 是默认 | 两家公司很可能已经各自有 IdP,SAML 是企业 IDP 互信的标准协议 |
| 实现架构 | IdP-to-IdP 联邦:A 的 IdP 配置 B 的 IdP 为 Trusted IdP,用户在 A 登录后访问 B 系统时由 B 的 IdP 信任 A 的断言 |
| 新方案边界 | OpenID Federation 1.0 定义了基于 Trust Anchor 和 Entity Statement 的联邦信任配置;它不能自动替换已有 SAML 互信,是否采用要看参与方是否支持该规范及其信任运营方式 |
场景 8:IoT 设备需要上报数据到云平台
需求:一个没有浏览器、没有键盘的物联网设备,需要向云端 API 发送数据。
| 考量 | 答案 |
|---|---|
| 推荐协议 | OAuth 2.0 Device Code Grant(首次配网时)或 Client Credentials(设备已有凭证) |
| Device Code 流程 | 设备向 IdP 请求一个 device_code + user_code → 用户在手机上访问验证 URL 输入 user_code 确认 → 设备轮询获得 Token |
| 为什么不是 Client Credentials 直接 | 设备出厂时可能没有唯一凭证,Device Code 提供了"人在环"的授权确认 |
| 后续会话 | 是否能获得 Refresh Token 取决于授权服务器、scope 和客户端策略;长期运行时还要明确 Refresh Token 的轮换、存储和撤销策略 |
场景 9:需要在反向代理层做统一认证
需求:用 Nginx Ingress 或 Traefik 对所有后端服务做统一的身份校验,未登录用户不能访问任何内部页面。
| 考量 | 答案 |
|---|---|
| 推荐协议 | OIDC(oauth2-proxy + ForwardAuth / auth-url) |
| Nginx Ingress | oauth2-proxy 作为 auth-url 指向的验证服务,Nginx 根据验证结果放行或重定向 |
| Traefik | ForwardAuth 中间件指向 oauth2-proxy 的 /oauth2/auth 端点 |
| 后端如何获取用户身份 | oauth2-proxy 会通过 X-Auth-Request-User、X-Auth-Request-Email、X-Auth-Request-Groups 等 HTTP Header 传递用户信息 |
| 详细配置 | 参见 Keycloak + oauth2-proxy 集成指南 和 Traefik ForwardAuth 配置 |
场景 10:需要从旧版 IAM 迁移到新版
需求:从自建 LDAP + 应用内认证迁移到 Keycloak 统一认证。
| 考量 | 答案 |
|---|---|
| 涉及协议 | LDAP(读取旧数据)→ SCIM 或直接导入(迁移到新平台)→ OIDC(新应用接入) |
| 迁移策略 | 1) Keycloak 先通过 LDAP User Federation 连接旧 LDAP——用户认证无缝继续;2) 分批将应用从直连 LDAP 改为对接 Keycloak OIDC;3) 最后把 LDAP 中的用户数据导入 Keycloak 内置数据库,断开 LDAP 依赖 |
| 风险控制 | 不要在迁移第一步就切 DNS 或改认证端点——先增强旧系统,再逐步替换 |
| 详细参考 | Keycloak LDAP/AD 联合配置指南 |
协议对比速查表
| 维度 | OAuth 2.0 | OIDC | SAML 2.0 | LDAP | SCIM 2.0 |
|---|---|---|---|---|---|
| 核心目的 | 授权 | 认证 | 联邦认证 | 目录查询 | 用户生命周期 |
| 标准化组织 | IETF | OpenID Foundation | OASIS | IETF | IETF |
| 规范基线 | RFC 6749(OAuth 2.0) | OpenID Connect Core 1.0 | SAML 2.0 | RFC 4510(LDAP) | RFC 7643/7644(SCIM 2.0) |
| 传输格式 | JSON (parameter) | JSON (JWT) | XML (SAML Assertion) | ASN.1 BER | JSON (REST) |
| 绑定/传输 | HTTP Redirect/Form POST | HTTP Redirect/Form POST | HTTP Redirect/POST/Artifact | TCP/TLS | HTTP REST |
| 实现复杂度 | 中等 | 中等(比 OAuth 多 ID Token 处理) | 高(XML 签名/加密复杂) | 低(简单查询) | 中等 |
| 调试难度 | 低(HTTP 抓包) | 低(JWT 在线解码) | 高(Base64 XML 签名验证) | 低 | 低 |
| 移动端支持 | ✅ 原生支持 | ✅ 原生支持 | ⚠️ 需要额外处理 | ❌ 不适用 | ❌ 不适用 |
| SPA 支持 | ✅ (PKCE) | ✅ (PKCE) | ⚠️ 不推荐 | ❌ | ❌ |
| 跨组织 SSO | ❌ 不是认证协议 | ✅ (OIDC Federation) | ✅ 原生支持 | ❌ | ❌ |
| 会话管理 | ❌ 无定义 | ✅ Session Management / Logout | ✅ SLO (单点登出) | ❌ | ❌ |
| 用户信息标准化 | ❌(各自实现) | ✅ UserInfo Endpoint | ✅ SAML Attributes | ✅ LDAP Schema | ✅ SCIM Schema |
| 发现/配置 | ❌ | ✅ Discovery (.well-known) | ✅ Metadata XML | ❌(手动配置) | ✅ ServiceProviderConfig |
| 角色/组映射 | ❌ | ✅ (Claims) | ✅ (Attributes) | ✅ (memberOf) | ✅ (Groups) |
| 客户端注册 | 动态或手动 | 动态或手动 | 手动(高成本) | N/A | N/A |
选型避坑指南
坑 1:用 OAuth 2.0 做认证
OAuth 2.0 是授权协议,不是认证协议。获取到 Access Token 不意味着你知道用户是谁——Access Token 是为资源访问设计的,格式和内容没有标准化。
正确做法:如果需要认证,使用 OIDC(在 OAuth 2.0 基础上增加 ID Token)。如果只有 OAuth 2.0 Access Token,应使用授权服务器提供的 Token Introspection 或资源服务自己的令牌校验规则;不要把 OIDC UserInfo Endpoint 当成通用 OAuth 认证接口,除非该授权服务器明确同时提供 OIDC 能力并定义了调用约定。
坑 2:把 ROPC 当成脚本或内网系统的快捷登录
grant_type=password 要求客户端直接接收用户密码。RFC 9700 §2.4 明确要求不得使用该授权类型:它扩大了密码泄露面,也无法自然承载 MFA、Passkey 等需要授权服务器参与的多步认证。内网、测试环境和“只有自己维护的客户端”都不是绕过这条边界的理由。
迁移判断:有人在场的交互式登录用 Authorization Code + PKCE;没有用户在场的服务调用用 Client Credentials,并为客户端凭证设置短有效期、最小 scope 和轮换机制;无浏览器设备用 Device Authorization Grant。旧系统暂时无法迁移时,应把它登记为隔离的遗留风险,而不是写进新架构决策树。
坑 3:在 Blazor/.NET/Java EE 之外用 SAML
SAML 的 XML 签名和加密对于现代 SPA 和移动 App 来说太重了。如果你在 React/Vue/Flutter 应用中接入 SAML,调试签名验证错误会让你怀疑人生。
正确做法:新应用默认用 OIDC;只有在对接已有 SAML IdP(如 AD FS、Shibboleth)时才用 SAML。如果后端是 .NET 或 Spring Security,这些框架对 SAML 的支持反而比 OIDC 更成熟——要具体情况具体分析。
坑 4:在公网暴露 LDAP
LDAP 的默认安全模型假设它在内网中运行。把 LDAP 暴露到互联网等于邀请攻击者暴力破解你的目录。
正确做法:用 SCIM 或 IdP 的 User Federation 功能封装 LDAP。如果需要外部访问,至少通过 VPN/Zero Trust 隧道,而不是直接开 389/636 端口。
坑 5:“五个协议全支持"的过度设计
一些团队会追求"完美”——同时支持 OIDC、SAML、LDAP、SCIM,再自己封装一套。结果每个协议都增加了注册、属性映射、密钥轮换和排错路径,维护责任却没有明确归属。
正确做法:先按已确认的应用和客户约束确定协议边界:新应用通常从 OIDC 开始;已有 SAML 信任关系才引入 SAML;LDAP 交给 IdP 的 User Federation 或目录适配层;只有下游确实需要自动开通、变更和禁用时才实现 SCIM。每增加一种协议,都要同时补齐密钥/元数据轮换、失败重试、审计和回滚方案。
坑 6:忽略 Token 生命周期和刷新策略
选完协议只是第一步。Access Token 设多长?Refresh Token Rotation 要不要开?登出时前端 Token 清了但后端 Token 还有效怎么办?
正确做法:根据资源风险、撤销能力、客户端类型和可接受的重新认证频率确定 Token 生命周期;不要把某个产品默认值当成通用安全基线。Refresh Token 应结合轮换、重放检测和安全存储设计。登出时是否需要通知 IdP,也要按协议和会话模型验证,不能只清理浏览器端状态。更多细节见 OAuth 2.0 Token 管理 和 OAuth 2.0 Security BCP。
IAM 协议选型 FAQ
Q1:OAuth 2.1 还在草案阶段,现有系统必须升级吗?
截至本页更新时,OAuth 2.1 仍是 IETF Internet-Draft,不是已发布的 RFC;不要把草案状态写成“已正式发布的协议版本”。现有 OAuth 2.0 系统也不需要为了版本号整体重写,但应按已发布的
OAuth 2.0 Security BCP(RFC 9700)逐项整改:授权码流程使用 PKCE,不使用 Implicit Grant 和 ROPC,并精确校验 redirect_uri。iss 参数则应结合 RFC 9207 的 Mix-Up Attack 防护要求评估。
这些安全改动可以在现有 OAuth 2.0 基础设施上分阶段实施。迁移时先做负向测试和小流量切换,不要用“支持 OAuth 2.1”替代具体验收项。详情见 OAuth 2.1 变化详解。
Q2: 中小企业只有 50 个员工,需要 IAM 协议吗?
需要,但不需要全量。 小团队可以先从 OIDC 统一登录开始;是否需要 SCIM 取决于下游系统是否支持、离职回收时效和人工操作是否已成为风险。SAML 只有在现有 IdP 或业务伙伴要求时才引入。本地帐号、LDAP 和云 IdP 的选择应以现有身份源、运维能力和故障回退路径为准,而不是员工数阈值。
Q3: SAML 和 OIDC 能共存吗?会有什么问题?
能共存,但有代价。 Keycloak、Okta、Entra ID 都支持同时做 SAML IdP 和 OIDC Provider。主要问题是:
- 会话一致性——用户在 OIDC 端登出,SAML 端的会话可能还在(SLO 的实现一致性因 IdP 而异)
- 运维复杂度——两个协议的错误排查路径完全不同
- 团队培训成本——需要有人同时懂 JWT 和 XML 签名
如果能统一用 OIDC,就不要引入 SAML。只有当业务要求(如客户用的是 AD FS)无法满足时,再加 SAML 支持。
Q4: 用 Keycloak 的话,协议选择会不会更简单?
会简化很多。 Keycloak 在协议适配层做得很好——你在 Keycloak 里配置一个 Client(OIDC)或 Client(SAML),后端会自动处理协议细节。开发者只需要知道"我应该创建一个 OIDC Client 还是 SAML Client"。
Keycloak 的不足是它不原生支持 SCIM 服务端(需要通过扩展或外部 SCIM Bridge),也不直接暴露 LDAP 端口(通过 User Federation 反向读取 LDAP,而不是作为 LDAP Server)。
Q5: LDAP 是否应该被淘汰?什么时候可以不学它?
短期不会淘汰,但可以不被它束缚。 如果你:
- 不在传统企业环境中工作(没有 AD)
- 正在做一个新项目,没有历史包袱
- 身份数据存储在数据库中而不是目录服务中
如果你的环境使用 Windows 域控或已有目录联邦,你几乎一定会遇到 AD;这时理解 LDAP/LDAPS 的连接、查询过滤器和属性映射是绕不过去的。若应用只通过 OIDC 接入 IAM,应用本身不必直接实现 LDAP。
Q6: OAuth 设备授权流程(Device Code)为什么不能用于 SPA?
因为安全模型不同。 Device Code Grant 假设设备有输出能力(显示 user_code)且用户有第二个设备(手机/电脑)来完成认证。SPA 在同一浏览器中完成所有操作,应该用 Authorization Code + PKCE。把 Device Code 用于 SPA 反而引入了不必要的轮询开销和安全风险(user_code 可能被截获)。
选型落地检查清单:先验证边界,再接入应用
协议名称写进架构图不等于接入完成。下面这组检查适合放在 IAM 应用接入的验收单里;它把“能登录”与“能安全运行”分开,避免上线后才发现协议选对了、信任边界却没落地。
| 检查项 | 最小验收动作 | 不通过时的处理 |
|---|---|---|
| OIDC 发现与签发者 | 从应用实际使用的 issuer URL 读取 /.well-known/openid-configuration,确认 authorization_endpoint、token_endpoint 和 jwks_uri 属于同一个发行者 | 不要先改应用代码;先修正 issuer、反向代理的外部 URL 或 TLS 终止配置 |
| 令牌用途 | 用测试令牌分别验证 iss、aud、exp 和权限声明;资源服务不能只验签名 | 回退到旧客户端或网关规则,同时保留失败令牌的 iss/aud(不要记录完整令牌) |
| 回调与 PKCE | 用一次成功授权和一次错误 redirect_uri/code_verifier 的请求做负向测试 | 禁止放宽回调地址或关闭 PKCE 作为“临时修复” |
| SAML 元数据 | 校验 Entity ID、ACS URL、签名证书有效期,并用过期证书演练拒绝行为 | 保留旧证书和旧 SP 配置,先完成证书轮换,再切换生产信任关系 |
| SCIM 生命周期 | 用测试用户演练创建、属性更新、active=false 和重复请求;确认下游重试不会产生重复账号 | 暂停自动推送,进入人工补偿队列;不要直接删除生产账号 |
OIDC 的发现文档定义了端点位置,OAuth 资源服务的令牌校验则必须结合具体授权服务器的约定;因此“发现接口返回 200”只能证明配置可读,不能证明应用已经完成授权校验。SCIM 的生命周期验证同样不能只看 HTTP 成功码,还要核对下游最终状态。
一次可回滚的接入顺序
- 先创建新客户端或新 SP,保留旧客户端不动;新配置只允许一个测试用户或测试组。
- 完成上表中的成功和负向测试,并记录 issuer、受众、回调地址、证书指纹和下游账号状态。
- 小范围切换流量,观察登录失败率、回调错误、令牌校验失败和 SCIM 重试队列。
- 出现异常时,将应用的认证入口切回旧客户端/旧 SP,暂停 SCIM 推送,保留新配置供定位;不要通过接受任意
aud、任意redirect_uri或跳过签名校验来止血。
这份清单的关键不是增加文档,而是为协议选型补上可证明的退出路径:每种协议都要有成功条件、失败信号和回滚动作。
与架构设计的衔接
协议选型和架构设计是 IAM 决策的两个维度:
- 协议回答"用什么语言传递身份信息"——本章覆盖
- 架构回答"身份数据放哪、谁做决策、如何扩展"——见 IAM 架构设计指南
二者需要同步决策。例如,选择了 SAML 意味着你的 IAM 需要支持 XML 签名验证和 Metadata 管理,这会增加运维复杂度从而影响架构的高可用设计。如果选择了 LDAP,你的架构中必须有一个组件承担 LDAP 查询的延迟风险。
建议先完成 协议选型(本章),再做 架构设计,最后确定 授权模型。这样可以先锁定外部接口契约,再把高可用、缓存和权限决策放进架构设计,减少后期返工。
如果你的 IAM 平台需要同时支持多种协议(如 OIDC + SAML),选型完成后建议直接参考 IAM 多协议集成实战,其中包含跨协议会话统一、属性映射和常见排错。
小结
IAM 协议选型的核心原则只有一条:选最匹配问题域的协议,而不是最"先进"的协议。
- OAuth 2.0 解决授权,OIDC 在其上解决认证
- SAML 在企业联邦中仍有不可替代的地位,但对新应用它已不是最优选择
- LDAP 是用户目录的"SQL"——底层基础设施,大多数开发者不需要直接和它打交道
- SCIM 把"建帐号"从手动操作变成 API 调用,是企业 IAM 自动化的重要标志
如果你只记住一件事,记住这个:拿到一个需求,先问"这是授权还是认证?是内部还是跨组织?有用户在场还是服务间通信?"——三个问题能帮你过滤掉 80% 的错误选项。