OAuth 2.0
OAuth 2.0 是授权框架,允许第三方应用在用户授权下有限访问受保护资源,不暴露用户密码。
#concept
#evergreen
#security
#http
[!info] related notes
- 上层协议: oidc(OIDC 基于 OAuth 2.0)
- 相关概念: sso, jwt, cookie-session-token, access-token, refresh-token
- 授权码安全: OAuth 授权码模式与 PKCE
- 客户端边界: OAuth Client 标识与认证、预注册、CIMD 与 DCR
OAuth 2.0
一句话定义
OAuth 2.0 是授权框架,允许第三方应用(Client)在用户(Resource Owner)授权下,有限访问受保护资源(Resource Server),不暴露用户密码。
核心角色
| 角色 | 说明 |
|---|---|
| Resource Owner | 资源所有者(通常是用户) |
| Client | 客户端应用(Web App / 原生 App / SPA) |
| Authorization Server | 授权服务器,签发 access_token |
| Resource Server | 资源服务器,持有受保护资源,校验 access_token |
四种授权模式
1. 授权码模式(Authorization Code)
最推荐,最安全。
用户 → Client: 访问应用
Client → 用户: 重定向到授权服务器(带 client_id, redirect_uri, scope, state)
用户 → 授权服务器: 登录并授权
授权服务器 → 用户: 重定向回 Client(带 code, state)
Client → 授权服务器: 用一次性 code、PKCE verifier(以及适用时的 client authentication)换 token
授权服务器 → Client: 返回 access_token(可选 refresh_token)
特点:
- code 通过浏览器回调传递,Token 在 token endpoint 交换;不同客户端类型的存储与传输方式有别
- 后端机密客户端可使用客户端认证;公开客户端(CLI、桌面、SPA)不能把静态内置 secret 当安全凭据
2. 授权码 + PKCE(Proof Key for Code Exchange)
授权码模式的增强版,专为 SPA 和原生 App 设计。
Client 生成 code_verifier 和 code_challenge
授权时带上 code_challenge
换 token 时发送 code_verifier
授权服务器校验两者匹配
- 不需要
client_secret(public client 无法安全存储密钥) - 防止授权码拦截攻击
- 现代客户端的标准安全措施;详细机制、局限和授权码重放威胁见 OAuth 授权码模式与 PKCE
3. 客户端凭证模式(Client Credentials)
服务对服务认证,没有用户参与。
Client → 授权服务器: client_id + client_secret
授权服务器 → Client: access_token
- 适合微服务间调用、后台任务
- 不产生 id_token,不涉及用户身份
4. 资源所有者密码凭证模式(Resource Owner Password Credentials)
不推荐,用户密码直接交给客户端。
Client → 授权服务器: username + password + client_id
授权服务器 → Client: access_token
- 仅用于极度信任的第一方客户端迁移场景
- 新系统不要使用
Token 类型
| Token | 用途 | 有效期 |
|---|---|---|
access_token | 访问受保护资源 | 短(通常 1 小时) |
refresh_token | 续签 access_token | 长(天/周/月),可撤销 |
access_token 的格式
- 不透明 token:授权服务器内部格式,资源服务器需调用 introspection 接口校验
- JWT:自包含,资源服务器可直接校验签名和声明
安全要点
state参数防 CSRFredirect_uri必须精确白名单匹配- code 短时有效且一次性使用
- client_secret 绝不能暴露给前端
- public client(SPA/App)必须用 PKCE
- access_token 不应存 localStorage(XSS 风险)
- 使用 HTTPS 传输
客户端标识、注册与委托授权
client_id 用于标识请求授权的应用,用户身份由授权服务器登录链路建立,真正的数据访问权来自受限 Token 及服务端策略。客户端识别、客户端认证、用户登录和授权同意不是同一件事,详见 OAuth Client 标识、认证与用户身份的区别。
MCP 等公共客户端生态可通过 预注册、CIMD 或 DCR 解决 client registration;成功注册后仍须完成用户授权及凭据兑换。对于需要每请求即时撤销的资源服务器,还要设计 Token 与 Grant 的授权生命周期。
与 OIDC 的关系
OAuth 2.0 只解决授权(你能访问什么资源),不解决认证(你是谁)。
oidc(OpenID Connect)在 OAuth 2.0 之上增加了身份层,通过 id_token 提供用户身份信息。