OpenID Connect (OIDC)
OIDC 基于 OAuth 2.0 增加身份层,通过 id_token 提供标准化用户身份认证,是现代 SSO 的首选协议。
#type / concept
#status / evergreen
#tech / security
#resource / http
[!info] related notes
OpenID Connect (OIDC)
一句话定义
OIDC 是基于 OAuth 2.0 的身份认证协议,在授权框架之上增加标准化身份层,通过 id_token 告诉客户端”这个用户是谁”。
OAuth 2.0 vs OIDC
| 维度 | OAuth 2.0 | OIDC |
|---|---|---|
| 解决什么 | 授权(你能访问什么) | 认证(你是谁)+ 授权 |
| 核心输出 | access_token | id_token + access_token |
| 用户身份 | 不标准化 | 标准化(JWT 格式 id_token) |
| 用途 | API 访问控制 | 单点登录、身份认证 |
OIDC = OAuth 2.0 + 身份层。
参与方
| 角色 | OIDC 术语 | 说明 |
|---|---|---|
| 用户 | End-User | 需要认证的人 |
| 客户端 | Relying Party (RP) | 依赖认证结果的应用 |
| 认证服务器 | OpenID Provider (OP) | 签发 id_token 的服务 |
三种流程
1. Authorization Code Flow(授权码流程)
最推荐,最安全。 用于有后端的 Web 应用。
1. Client 跳转 OP 的 /authorize(带 client_id, redirect_uri, scope=openid, state, nonce)
2. 用户登录并授权
3. OP 重定向回 Client(带 code, state)
4. Client 后端用 code + client_secret 调 /token
5. OP 返回 id_token + access_token(可选 refresh_token)
6. Client 校验 id_token(签名 / iss / aud / exp / nonce)
7. 建立本地会话
2. Implicit Flow(隐式流程)
已不推荐。 曾经用于 SPA,但 token 直接暴露在浏览器中。
现代 SPA 应改用 Authorization Code + PKCE。
3. Hybrid Flow(混合流程)
授权码 + 部分 token 同时返回。适用于需要快速拿到用户信息但又不完全信任前端的场景。
id_token
OIDC 的核心产出,JWT 格式,包含用户身份声明:
{
"iss": "https://sso.example.com",
"sub": "user-123",
"aud": "client-app-1",
"exp": 1700000000,
"iat": 1699996400,
"nonce": "abc123",
"name": "张三",
"email": "zhangsan@example.com"
}
必须校验的字段
| 字段 | 校验内容 |
|---|---|
iss | 是否来自可信 OP |
sub | 用户唯一标识(不变) |
aud | 是否匹配当前 client_id |
exp | 是否未过期 |
nonce | 是否与请求时发送的一致(防重放) |
| 签名 | 使用 OP 的公钥验证 JWT 签名 |
标准 Claims
| Claim | 含义 |
|---|---|
sub | 用户唯一标识(必须) |
name | 全名 |
given_name / family_name | 名 / 姓 |
email / email_verified | 邮箱 / 是否验证 |
phone_number / phone_number_verified | 手机号 / 是否验证 |
picture | 头像 URL |
preferred_username | 首选用户名 |
scope 控制返回信息
| scope | 返回的 Claims |
|---|---|
openid | 必须,返回 sub |
profile | name, given_name, family_name, picture 等 |
email | email, email_verified |
phone | phone_number, phone_number_verified |
address | address |
/userinfo 端点
如果 id_token 里信息不够,Client 可以用 access_token 调用 OP 的 /userinfo 接口获取更多信息。
会话管理
OIDC 定义了会话管理扩展:
- Session Management:通过 iframe 检测 OP 登录状态变化
- Front-Channel Logout:OP 通过浏览器重定向通知各 RP 登出
- Back-Channel Logout:OP 后端直接调用各 RP 的 logout 接口(更安全)
- RP-Initiated Logout:用户从 RP 发起全局登出
发现端点(Discovery)
OIDC 提供 .well-known/openid-configuration 端点,自动暴露 OP 的能力:
GET https://sso.example.com/.well-known/openid-configuration
返回:
issuerauthorization_endpointtoken_endpointuserinfo_endpointjwks_uri(公钥地址)scopes_supportedresponse_types_supportedgrant_types_supported
安全要点
state防 CSRFnonce防 id_token 重放redirect_uri精确白名单- public client 用 PKCE
- id_token 短效
- 不要依赖 Implicit Flow
- JWT 签名严格校验
- key rotation 支持
与 SAML 对比
| 维度 | OIDC | SAML |
|---|---|---|
| 数据格式 | JSON / JWT | XML |
| 开发体验 | RESTful,现代 | 复杂,XML 繁琐 |
| 适用场景 | 现代 Web/App/API | 老企业系统、政企 |
| 生态 | 活跃,主流 | 稳定,存量多 |