OAuth 2
国际互联网工程任务组文档 | 文档地址 | 说明 |
---|---|---|
OAuth 2.0 | https://datatracker.ietf.org/doc/html/rfc6749 | |
OAuth 2.1 | https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-10 | 此协议处于草案阶段 |
- 本文以 OAuth 2.1 协议原文进行编写,增加了作者的个人理解
兼容性
- OAuth 2.1 兼容 OAuth 2.0
- OAuth 2.1 具有高扩展性(以 org.springframework.security:spring-security-oauth2-authorization-server 为例)
- OAuth 2.1 启用了严格的匹配重定向地址(不支持通配符)
- OAuth 2.1 删除了隐式授权(即:
response_type=token
)
角色
- 此处仅对各种角色(资源所有者、资源服务器、客户、授权服务器)做出最基础、最简单的介绍。
名称 | 缩写 |
---|---|
资源所有者 | RO |
资源服务器 | RS |
授权服务器 | AS |
资源所有者
- 通常代表
用户
- 可以将受保护的资源(如:手机号、邮箱、导航记录等)授权给其他使用者。
- 用户使用某个微信小程序时,可以给这个小程序授权微信绑定的手机号。
- 用户使用 GitHub/Gitee 登录某个网站时,需要将邮箱授权给该网站。
- 用户使用导航时,可以将实时导航信息分享给家人和朋友。
资源服务器
- 并非真正的物理服务器,而是一个服务(或程序),如:购物车服务、订单服务等。
- 处理受保护资源的服务,可以使用访问令牌(Token)访问并获取响应的数据。
- 购物车服务:用户用于处理待购买商品的服务,如:将商品添加到购物车、将商品从购物车删除、从购物车中结算部分或全部商品等
- 订单服务:用户用于下单、取消下单的服务
客户
- 用于申请授权的网站、服务(或程序)等
- 用户使用某个微信小程序时,这个小程序就是客户。
- 用户使用 GitHub/Gitee 登录某个网站时,该网站就是客户。
A 服务
(或程序)不经过用户授权就想操作(增删改查)B 服务
(或程序)的数据(通常用于不同系统间的对接,如:定时上传、下载数据), 则A 服务
就是客户
授权服务器
- 并非真正的物理服务器,而是一个服务(或程序)。
- 请求授权时,用于成功验证资源所有者后,向客户颁发访问令牌的服务(或程序)。
协议流程
- 为了方便大家理解下列流程,此处使用
微博
登录CSDN
来举例,条件如下:- CSDN 已经绑定了 微博 账户
- 退出浏览器登陆的 CSDN 账户
- 此处为简化流程介绍,不特指哪种授权类型,如需了解某种授权类型,请查看:
shell
+--------+ +---------------+
| |--(1)- Authorization Request ->| Resource |
| | | Owner |
| |<-(2)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(3)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(4)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(5)----- Access Token ------>| Resource |
| | | Server |
| |<-(6)--- Protected Resource ---| |
+--------+ +---------------+
- (1) 用户访问 CSDN 的 个人资料页面
Client
代表 CSDN 网站Client
代表 用户 行为,比如:此处访问的 CSDN 的 个人资料页面
- (2) 由于 CSDN 的 个人资料页面 需要登陆才能访问,所以 CSDN 跳转到登录页面
- (3) 点击 微博 登录
- 使用 微博 扫码登陆成功(图中未包含)
- 微博 重定向到 CSDN 网站(图中未包含)
- CSDN 网站获取到 微博 用户信息,并根据 微博 用户的信息查询绑定的 CSDN 用户(图中未包含)
- (4) 返回 授权令牌
- (5) 使用 授权令牌,访问 个人资料页面
- (6) 查看到 个人资料页面,即:受保护的资源
授权码模式
- 此处是 协议流程 的
授权码模式
的详细流程 - 为了方便大家理解下列流程,此处使用
微博
登录CSDN
来举例,条件如下:- CSDN 已经绑定了 微博 账户
- 退出浏览器登陆的 CSDN 账户
+----------+
| Resource |
| Owner |
+----------+
^
|
|
+-----|----+ Client Identifier +---------------+
| .---+---------(1)-- & Redirect URI ------->| |
| | | | | |
| | '---------(2)-- User authenticates --->| |
| | User- | | Authorization |
| | Agent | | Server |
| | | | |
| | .--------(3)-- Authorization Code ---<| |
+-|----|---+ +---------------+
| | ^ v
| | | |
^ v | |
+---------+ | |
| |>---(4)-- Authorization Code ---------' |
| Client | & Redirect URI |
| | |
| |<---(5)----- Access Token -------------------'
+---------+ (w/ Optional Refresh Token)
名称 | 解释 |
---|---|
User-Agent | 代表用户行为/用户操作/用户浏览器 |
Authorization Server | 微博授权服务器 |
Client | 代表 CSDN 服务器 |
Resource Owner | 代表 CSDN 需要登陆才能访问的网址 |
Client Identifier | CSDN 在 微博 的 客户身份标识,即:用微博登陆 CSDN 时网址中的 client_id=2601122390 |
Redirect URI | CSDN 接收 微博 授权码的网址,即:用微博登陆 CSDN 时网址中的 https://passport.csdn.net/account/login?pcAuthType=sinat&newAuth=true |
User authenticates | 用微博登陆 CSDN 时,使用 微博 扫码确认登录 |
Authorization Code | 用微博登陆 CSDN 时,微博给 CSDN 生成的一个只能使用一次的授权 code,有效期只有几分钟 |
Access Token | 用微博登陆 CSDN 时,微博给 CSDN 颁发的授权令牌 (也叫授权Token,授权令牌存在有效期),可用于获取微博用户信息 |
Optional Refresh Token | 用微博登陆 CSDN 时,微博可能会返回刷新令牌(也叫刷新Token),用于重新生成微博授权令牌 (无需用户重复登陆,刷新Token存在有效期) |
- 用户(User-Agent) 在 CSDN 登录页点击 微博 登录按钮(Resource Owner)
- (1) CSDN 跳转到 微博 登陆页面,示例网址: https://api.weibo.com/oauth2/authorize?client_id=2601122390&response_type=code&redirect_uri=https%3A%2F%2Fpassport.csdn.net%2Faccount%2Flogin%3FpcAuthType%3Dsinat%26newAuth%3Dtrue###
- 微博登录页的网址携带
client_id=2601122390
- 其中
2601122390
是 CSDN 在 微博 的客户身份标识(Client Identifier)
- 其中
- 微博登录页的网址携带
redirect_uri=https%3A%2F%2Fpassport.csdn.net%2Faccount%2Flogin%3FpcAuthType%3Dsinat%26newAuth%3Dtrue
- 其中
https%3A%2F%2Fpassport.csdn.net%2Faccount%2Flogin%3FpcAuthType%3Dsinat%26newAuth%3Dtrue
是授权成功后的重定向地址(Redirect URI),由https://passport.csdn.net/account/login?pcAuthType=sinat&newAuth=true
计算encodeURIComponent
之后的结果
- 其中
- 微博登录页的网址携带
response_type=code
- 授权类型,
code
代表授权码模式
- 授权类型,
- 微博登录页的网址
可能
携带status=xxx
- 状态码,用于防止攻击,可选,不是必须携带的
- 微博登录页的网址携带
- (2) 使用 微博 扫码确认登录
- (3) 微博 重定向到
https://passport.csdn.net/account/login?pcAuthType=sinat&newAuth=true
- 携带
授权码 code
可能
携带状态码 status=xxx
,来自于上面的 (1)- 此地址就是 CSDN 服务器(Client)
- 携带
- (4) CSDN 使用参数访问 微博 授权服务器,参数包含:
- 授权码 code(Authorization Code)
- 重定向地址(Redirect URI)
- 客户身份标识(Client Identifier)
- 客户身份凭证(Client Secret)
- (5) 微博授权服务器完成验证后,返回数据,如:
- 授权令牌(Access Token)
- 授权令牌有效期
- 授权范围(scope)
- 刷新令牌(Refresh Token,可能携带,需要在申请授权时添加刷新令牌的范围
refresh_token
)