2. OIDC协议核心概念精讲
在企业身份平台集成中,OIDC(OpenID Connect)几乎总是与 OAuth 2.0 同时出现,但两者解决的问题并不相同。OAuth 2.0 的核心目标是授权:让客户端在用户许可下获得访问受保护资源的权限,它定义的是 access token 的获取与使用方式,本身并不规定“用户是谁”。OIDC 则是在 OAuth 2.0 之上增加的一层身份认证协议,它复用 OAuth 2.0 的授权码流程、端点与令牌机制,额外引入 ID Token、UserInfo 端点以及一组标准 Claims,用来回答“当前登录的用户是谁、认证发生在何时、由谁完成”。理解这一层关系,是后续所有集成配置的基础。
OIDC 与 OAuth 2.0 的层次关系
可以把 OIDC 看作 OAuth 2.0 的一个“身份扩展包”。在授权码流程中,客户端把用户重定向到授权端点,用户完成认证后,授权服务器返回授权码,客户端再用授权码换取令牌。OIDC 的关键变化在于:请求中必须包含 openid 这个 scope,授权服务器在返回 access token 的同时,额外返回一个 ID Token。access token 用于访问资源,ID Token 用于向客户端证明用户身份。两者职责分离,不能混用。
需要特别注意的是,OIDC 并没有改变 OAuth 2.0 的令牌交换机制,而是通过标准化的 Claims 和端点,让客户端能够以可验证的方式获得用户身份信息。企业身份平台通常同时扮演 OAuth 2.0 授权服务器和 OIDC 提供者(OP)两个角色,因此集成时既要配置 OAuth 2.0 的客户端信息,也要关注 OIDC 特有的发现文档、签名算法和 Claims 映射。
ID Token:身份认证的核心载体
ID Token 是 OIDC 最重要的产物,它是一个 JWT(JSON Web Token),由三部分组成:头部、载荷和签名。头部声明签名算法,例如 RS256;载荷包含一组标准 Claims;签名用于客户端验证令牌确实由可信的 OP 签发且未被篡改。客户端拿到 ID Token 后,必须完成以下校验,缺一不可:
- 签名验证:使用 OP 公布的 JWKS(JSON Web Key Set)公钥验证签名,确认令牌来源可信。
- iss 校验:确认签发者与预期 OP 的 issuer 完全一致。
- aud 校验:确认受众包含本客户端的 client_id,防止令牌被其他应用冒用。
- exp / iat 校验:确认令牌未过期,且签发时间在合理范围内。
- nonce 校验:如果授权请求中携带了 nonce,必须确认 ID Token 中的 nonce 与之一致,防止重放攻击。
一个典型的 ID Token 载荷示例如下(示例数据,非真实令牌):
{
"iss": "https://idp.example.com",
"sub": "00u1a2b3c4d5e6f7g8h9",
"aud": "0oa1b2c3d4e5f6g7h8i9",
"exp": 1735689600,
"iat": 1735686000,
"nonce": "n-0S6_WzA2Mj",
"auth_time": 1735685980,
"name": "张伟",
"email": "zhangwei@example.com",
"preferred_username": "zhangwei"
}
其中 sub 是用户在该 OP 下的唯一标识,企业集成时应以 sub 作为稳定主键,而不是 email 或 username,因为后者可能被修改或复用。auth_time 表示实际认证发生的时间,对于需要强制重新认证的敏感操作非常有用。
UserInfo 端点与 Claims 获取策略
ID Token 中的 Claims 通常只包含最基础的身份信息。如果客户端需要更多用户属性,例如部门、职位、手机号,可以调用 UserInfo 端点。调用时在 HTTP 请求头中携带 Authorization: Bearer <access_token>,OP 验证 access token 有效后返回 JSON 格式的用户 Claims。
这里有一个常见的集成误区:把 UserInfo 当作唯一的信息来源,每次登录都调用。更合理的策略是优先使用 ID Token 中的 Claims,因为它在令牌交换阶段已经随令牌一起返回,无需额外网络请求;只有当 ID Token 中缺少必要属性时,才按需调用 UserInfo。这样既能减少延迟,也能降低对 OP 的请求压力。
Scope 与 Claims 的语义映射
Scope 是 OAuth 2.0 中用于表达权限范围的参数,OIDC 在此基础上定义了与身份相关的标准 Scope,并规定了每个 Scope 对应应返回哪些 Claims。理解这层映射关系,才能正确配置客户端请求,避免“请求了但拿不到”或“拿到了不该拿的”问题。
| Scope | 含义 | 典型返回 Claims |
|---|---|---|
openid |
声明使用 OIDC,必须包含 | sub(ID Token 必含) |
profile |
请求基本个人资料 | name、family_name、given_name、preferred_username、picture |
email |
请求邮箱信息 | email、email_verified |
address |
请求地址信息 | address(结构化 JSON) |
phone |
请求电话信息 | phone_number、phone_number_verified |
企业身份平台通常还会定义自定义 Scope,例如 department、employee_id,用于映射企业内部组织架构属性。配置时需要在 OP 侧为客户端授权这些 Scope,并在客户端请求中显式声明。需要注意的是,Scope 只是“请求”,OP 是否返回对应 Claims 还取决于用户授权、客户端配置以及 OP 的策略。因此集成测试时,应逐一验证每个 Scope 实际返回的 Claims 集合,而不是假设请求了就一定会返回。
总结来看,OIDC 在 OAuth 2.0 的授权框架上叠加了身份认证能力:openid scope 触发 ID Token 返回,ID Token 承载可验证的身份 Claims,UserInfo 端点提供按需补充属性的通道,Scope 则决定了 Claims 的请求范围。掌握这四者之间的语义与边界,是后续配置企业身份平台、排查登录问题、设计用户会话的基础。