1. OAuth2 概述:协议发展、核心角色与授权码流程
OAuth2 是目前业界最广泛使用的授权框架,它允许第三方应用(客户端)在资源所有者(用户)授权的前提下,安全地访问托管在资源服务器上的受保护资源,而无需暴露用户的长期凭证(如密码)。本章将梳理 OAuth2 的发展脉络、定义其核心角色,并解析最经典的授权码流程。
1.1 OAuth2 协议发展历史
OAuth 协议经历了从专有方案到标准化、从复杂到简洁的演进过程,其关键里程碑如下表所示:
| 版本 | 发布年份 | 核心特点 | 主要问题 / 改进 |
|---|---|---|---|
| OAuth 1.0 | 2007 | 基于签名与令牌的授权;不依赖 TLS | 实现复杂,签名算法易出错;缺乏可扩展性 |
| OAuth 1.0a | 2009 | 修复会话固定攻击漏洞 | 安全性提升,但复杂度未降低 |
| OAuth 2.0 | 2012 | 简化流程,依赖 TLS,引入 Bearer Token | 大幅降低实现门槛;成为行业标准(RFC 6749) |
| OAuth 2.1 | 2021 (草案) | 合并安全最佳实践,废弃隐式模式等不安全流程 | 强制 PKCE、禁止 Resource Owner Password Credentials 流程 |
安全提示: 本课程所有实战内容均基于 OAuth 2.1 的安全建议。在实际项目中,应避免使用已废弃的隐式授权流程,并始终为授权码流程启用 PKCE 扩展。
1.2 核心角色
OAuth2 协议定义了四个核心角色,它们之间的交互构成了授权的基础。理解每个角色的职责是掌握安全错误码与断言权限验证的前提。
- 资源所有者(Resource Owner):通常是用户,拥有对受保护资源的访问权限。其核心动作是授权或拒绝客户端的访问请求。
- 客户端(Client):需要访问资源所有者资源的第三方应用(如 Web 应用、移动 App、单页应用)。它必须事先在授权服务器注册,并获取
client_id和client_secret。 - 授权服务器(Authorization Server):负责验证资源所有者身份、获取授权,并向客户端颁发访问令牌(Access Token)和可选的刷新令牌(Refresh Token)。它是整个授权流程的核心枢纽。
- 资源服务器(Resource Server):托管受保护资源的服务器。它接收并验证客户端出示的访问令牌,根据令牌中的权限范围决定是否返回资源。
关键概念: 授权服务器与资源服务器在物理上可以是同一台服务器,但在逻辑上是两个独立的角色。在安全架构中,通常建议将它们分离,以便独立扩展和强化安全策略。
1.3 授权码流程简介
授权码流程(Authorization Code Flow)是 OAuth2 中最安全、最常用的流程,特别适用于有后端的 Web 应用。其核心思想是:客户端通过浏览器获取一个临时的“授权码”,然后使用该授权码在后台(通过 HTTPS)向授权服务器换取访问令牌。这样,访问令牌永远不会暴露在用户浏览器中。
下图展示了授权码流程的完整交互步骤:
上述流程的详细步骤说明:
- 用户访问客户端:用户通过浏览器访问客户端应用,触发登录或资源访问请求。
- 客户端重定向:客户端将用户浏览器重定向到授权服务器的授权端点,并附上
client_id、redirect_uri、response_type=code和scope等参数。 - 用户认证与授权:授权服务器展示登录页面,用户输入凭证进行身份验证,并确认授权范围。
- 返回授权码:授权服务器通过重定向将授权码(
code)发送回客户端指定的redirect_uri。 - 客户端接收授权码:客户端从 URL 查询参数中提取授权码。
- 客户端交换令牌:客户端在后台(服务器端)向授权服务器的令牌端点发送 POST 请求,包含
code、client_id、client_secret和redirect_uri。 - 授权服务器返回令牌:授权服务器验证授权码和客户端身份后,返回
access_token和可选的refresh_token。 - 客户端请求资源:客户端使用
access_token向资源服务器发起 API 请求。 - 资源服务器返回资源:资源服务器验证令牌的有效性和权限范围,返回受保护的资源数据。
安全警告: 授权码流程的安全性高度依赖于
client_secret 的保密性。对于无法安全存储 client_secret 的客户端(如单页应用或原生应用),必须使用 PKCE(Proof Key for Code Exchange)扩展来防止授权码拦截攻击。本课程后续章节将详细讲解 PKCE 的实现与验证。
1.4 核心角色关系总结
下表总结了四个核心角色在授权码流程中的关键交互与安全职责:
| 角色 | 主要交互对象 | 关键安全职责 | 常见安全错误 |
|---|---|---|---|
| 资源所有者 | 客户端、授权服务器 | 谨慎授权,确认权限范围 | 盲目点击“授权”按钮,未检查应用权限 |
| 客户端 | 资源所有者、授权服务器、资源服务器 | 保护 client_secret,验证 redirect_uri |
未校验 state 参数导致 CSRF 攻击 |
| 授权服务器 | 资源所有者、客户端 | 正确验证用户身份,颁发有效令牌 | 未验证 redirect_uri 导致开放重定向 |
| 资源服务器 | 客户端 | 严格验证令牌签名、有效期和权限范围 | 未校验令牌是否被撤销或过期 |