前言

在单点登录(SSO)和身份认证领域,OAuth2、OIDC(OpenID Connect)和 SAML 是目前使用最广泛的三种协议。它们经常被同时提到,但解决的问题却并不完全相同:

  • OAuth2:解决授权(Authorization)问题——“允许第三方应用访问我的资源”。
  • OIDC:在 OAuth2 基础上扩展,解决认证(Authentication)问题——“证明我是谁”。
  • SAML:一个较早期的、基于 XML 的认证+授权协议,主要用于企业 SSO。

本文作为自己的笔记,用于系统梳理三者的关系、差异及各自的适用场景。

一、核心概念对比

1.1 一句话定义

协议 全称 核心定位 诞生时间
OAuth2 Open Authorization 2.0 授权框架:让第三方应用在用户授权下访问受保护资源 2012(RFC 6749)
OIDC OpenID Connect 1.0 身份认证层:基于 OAuth2 之上的身份认证协议 2014
SAML Security Assertion Markup Language 认证+授权协议:基于 XML 的企业级 SSO 协议 2005(SAML 2.0)

1.2 关键差异速览

维度 OAuth2 OIDC SAML
主要用途 授权(Authorization) 认证(Authentication) 认证 + 授权
数据格式 JSON JSON / JWT XML
传输方式 HTTP + Bearer Token HTTP + Bearer Token HTTP POST / Redirect(XML 签名)
令牌类型 Access Token(+ Refresh Token) ID Token(JWT)+ Access Token SAML Assertion(XML)
用户身份信息 不包含(需额外接口获取) 包含在 ID Token 中 包含在 SAML Assertion 中
适用场景 开放平台、API 授权 Web / 移动端 SSO、社交登录 企业内部 SSO、B2B
复杂度
移动端支持

二、OAuth2 详解

2.1 角色定义

  • Resource Owner(资源所有者):通常是用户本人。
  • Client(客户端):希望访问用户资源的第三方应用。
  • Authorization Server(授权服务器):签发 Access Token。
  • Resource Server(资源服务器):存放用户资源,校验 Token 后返回数据。

2.2 四种标准授权模式

  1. 授权码模式(Authorization Code):最常用、最安全,适用于有后端的 Web 应用。
  2. 简化模式(Implicit):纯前端应用,已不推荐,改用 PKCE。
  3. 密码模式(Password):客户端直接持有用户密码,信任度要求极高。
  4. 客户端模式(Client Credentials):无用户参与,应用对应用授权。

新增扩展:PKCE(公共客户端保护)、Device Code(设备码模式,适用于电视/IoT)。

2.3 授权码流程(简图)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sequenceDiagram
participant U as User
participant C as Client
participant AS as Authorization Server
participant RS as Resource Server

U->>C: 访问客户端
C->>AS: 重定向到授权页(response_type=code)
U->>AS: 登录并同意授权
AS->>C: 回调并返回 code
C->>AS: 用 code 换取 access_token
AS->>C: 返回 access_token
C->>RS: 携带 access_token 请求资源
RS->>C: 返回资源数据

2.4 OAuth2 的局限

  • 只管授权不管认证:Access Token 仅表示”有权限访问某资源”,并不能直接证明”用户是谁”。
  • 无标准化的用户信息接口:不同厂商的 userinfo 接口字段不统一(这也是 OIDC 出现的原因)。
  • Token 格式不统一:既可以是随机字符串(opaque),也可以是 JWT。

三、OIDC 详解

3.1 与 OAuth2 的关系

一句话概括:OIDC = OAuth2 + 身份认证层(ID Token) + 标准化 UserInfo 接口

OIDC 完全复用 OAuth2 的授权流程和端点,只是在此基础上:

  1. 新增 openid 这个 scope,用于标识这是一个身份认证请求。
  2. 在 Token 响应中额外返回一个 ID Token(JWT 格式)。
  3. 标准化了 /userinfo 端点与用户属性字段(如 subemailname)。
  4. 标准化了 Discovery(/.well-known/openid-configuration)与 JWK 公钥端点。

3.2 ID Token 结构

ID Token 是一个标准的 JWT,包含如下典型 Claims:

1
2
3
4
5
6
7
8
9
10
{
"iss": "https://accounts.example.com", // 签发者
"sub": "248289761001", // 用户唯一标识
"aud": "client-id-xxx", // 接收方
"exp": 1715241600, // 过期时间
"iat": 1715238000, // 签发时间
"nonce": "n-0S6_WzA2Mj", // 防重放
"email": "user@example.com",
"name": "Ke Wen"
}

客户端收到后通过 IdP 的公钥验签,即可安全识别用户身份,无需再调用接口。

3.3 OIDC 与 OAuth2 的核心差异

维度 OAuth2 OIDC
解决的问题 授权 认证(+ 授权)
额外的 scope 自定义 必须包含 openid
返回的令牌 Access Token Access Token + ID Token
ID Token 格式 —— 必须是 JWT
用户信息获取 厂商自定义接口 标准 /userinfo 端点
元数据发现 无标准 标准 Discovery 文档
是否能表明”我是谁” 不能(Access Token 不应被客户端解析) (ID Token 是为客户端设计的)

⚠️ 常见误用:很多系统直接把 OAuth2 的 Access Token 当作”登录凭证”使用并解析其内容,这是反模式。Access Token 是给资源服务器用的,ID Token 才是给客户端用来识别用户身份的。

3.4 典型流程

OIDC 的 Authorization Code Flow 与 OAuth2 几乎一致,只是请求中带上 scope=openid

1
2
3
4
5
6
7
GET /authorize?
response_type=code
&client_id=xxx
&redirect_uri=https://app.example.com/cb
&scope=openid profile email
&state=xyz
&nonce=n-0S6_WzA2Mj

拿到 code 后换 token 时,响应会同时返回 access_tokenid_token

四、SAML 详解

4.1 角色定义

  • Principal:终端用户。
  • Service Provider(SP):服务提供方(业务系统)。
  • Identity Provider(IdP):身份提供方(统一认证中心)。

4.2 核心流程(SP-Initiated SSO)

1
2
3
4
5
6
7
8
9
10
11
12
13
sequenceDiagram
participant U as User
participant SP as Service Provider
participant IdP as Identity Provider

U->>SP: 访问业务系统
SP->>U: 返回 SAMLRequest(浏览器重定向到 IdP)
U->>IdP: 打开登录页
U->>IdP: 提交账号密码
IdP->>U: 返回 SAMLResponse(含 Assertion, 通过浏览器 POST 回 SP)
U->>SP: 自动 POST SAMLResponse
SP->>SP: 校验签名,建立本地会话
SP->>U: 返回业务页面

4.3 SAML Assertion

SAML 的”令牌”是一段 XML,包含三类声明:

  • Authentication Statement:认证方式、时间。
  • Attribute Statement:用户属性(邮箱、部门、角色等)。
  • Authorization Decision Statement:授权结论(可选)。

使用 XML 签名(XMLDSig)保证完整性,可选 XML 加密保护敏感字段。

4.4 特点

  • 基于 XML:报文大、解析复杂、对浏览器原生不友好。
  • 依赖浏览器:主要靠 HTTP-Redirect / HTTP-POST binding,移动端和 SPA 不方便。
  • 企业友好:与 AD FS、Okta、Azure AD、Keycloak 等企业身份源无缝集成。
  • 一次登录,多系统互通:是传统企业 SSO 的事实标准。

五、三者关系总览

1
2
3
4
5
6
7
8
9
graph TB
A[身份与访问管理需求] --> B[需要授权第三方访问 API]
A --> C[需要证明用户身份]
A --> D[企业内部多系统 SSO]
B --> E[OAuth2]
C --> F[OIDC]
F -.基于.-> E
D --> G[SAML]
D -.新系统也可选.-> F
  • OIDC 是 OAuth2 的超集:所有 OIDC 服务都是 OAuth2 服务,反之不成立。
  • SAML 与 OIDC 在功能上有重叠,都能做 SSO,但技术栈和生态完全不同。
  • 现代新系统优先选择 OIDC;遗留企业系统常见 SAML;开放平台 API 使用 OAuth2。

六、使用场景对比

6.1 OAuth2 典型场景

  • 开放平台 API 授权:如 GitHub、微信开放平台,允许第三方应用代表用户调用 API。
  • 前后端分离应用的资源访问控制:自家应用的 API 鉴权(虽然严格来说这是简化用法)。
  • 服务间调用(Client Credentials):微服务之间的 M2M 认证。
  • IoT / 设备授权(Device Code):电视、打印机等无键盘设备。

6.2 OIDC 典型场景

  • 社交登录 / 第三方登录:Google、Apple、微信(微信更接近 OAuth2)等”Sign in with XXX”。
  • 企业内部新建系统 SSO:使用 Keycloak、Auth0、Azure AD 作为 IdP。
  • 移动端 App 登录:配合 PKCE 的 Authorization Code Flow。
  • Zero Trust 架构下的身份层:统一身份源,下发 JWT。

6.3 SAML 典型场景

  • 大型企业内部 SSO:如 Office 365、Salesforce、Jira、Confluence 等企业 SaaS 接入公司 AD。
  • B2B 联邦身份:公司 A 的员工通过公司 A 的 IdP 登录公司 B 的系统。
  • 政务、金融等对合规要求高的场景:SAML 成熟、审计链路清晰。
  • 遗留系统整合:许多老牌 SaaS 仍以 SAML 为首选接入方式。

七、如何选型

你的需求 推荐协议
我要做”微信登录/Google 登录”这样的第三方登录 OIDC(或封装过的 OAuth2)
我要开放 API 让别的公司/开发者接入 OAuth2
公司内部要做几十个系统的统一登录,且多为 Web 应用 OIDC(新建)或 SAML(历史原因)
公司要接入 Salesforce / Workday / Office 365 等企业 SaaS SAML(通常只能选它)
移动端 / SPA 登录 OIDC + PKCE
微服务之间的机机调用 OAuth2 Client Credentials(或 mTLS)
设备类登录(无键盘) OAuth2 Device Flow

八、常见疑问(FAQ)

Q1:OIDC 既然能做认证,是否还需要 OAuth2?
A:OIDC 本身就是 OAuth2 的扩展,部署 OIDC 时天然就包含 OAuth2。真正的问题是”要不要用 ID Token 代替 Access Token 做鉴权”——不要,两者职责不同。

Q2:能用 SAML 代替 OIDC 吗?
A:功能上大部分可以,但 SAML 在移动端、SPA 上体验差,且 XML 对开发者不友好,新系统不推荐。

Q3:Access Token 为什么不能用来识别用户?
A:Access Token 是”访问凭证”,其格式、受众都是资源服务器,客户端不应对其做解析。用 ID Token 或调用 /userinfo 才是正确做法。

Q4:JWT == OIDC 吗?
A:不等于。JWT 只是一种令牌格式,OIDC 强制 ID Token 为 JWT,但 OAuth2 的 Access Token 可以是 JWT 也可以是 opaque string。

Q5:SAML 已经过时了吗?
A:在企业 SaaS 市场仍然是主流,短期内不会消失;但新系统设计优先考虑 OIDC。

九、总结

  • OAuth2 是授权,OIDC 是认证,SAML 是早期的企业级认证+授权
  • OIDC 建立在 OAuth2 之上,通过 ID Token 和标准化的 UserInfo 接口补齐了”身份认证”能力。
  • SAML 和 OIDC 目标类似,但技术栈分别是 XML 和 JSON/JWT,生态上 SAML 偏企业传统系统,OIDC 偏现代 Web/移动应用。
  • 选型时以业务场景 + 接入对象为准:开放 API 选 OAuth2,用户登录选 OIDC,企业 SaaS 互联选 SAML。