Skip to content

OAuth 2

国际互联网工程任务组文档文档地址说明
OAuth 2.0https://datatracker.ietf.org/doc/html/rfc6749
OAuth 2.1https://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

资源所有者

  • 通常代表用户
  • 可以将受保护的资源(如:手机号、邮箱、导航记录等)授权给其他使用者。
    1. 用户使用某个微信小程序时,可以给这个小程序授权微信绑定的手机号。
    2. 用户使用 GitHub/Gitee 登录某个网站时,需要将邮箱授权给该网站。
    3. 用户使用导航时,可以将实时导航信息分享给家人和朋友。

资源服务器

  • 并非真正的物理服务器,而是一个服务(或程序),如:购物车服务、订单服务等。
  • 处理受保护资源的服务,可以使用访问令牌(Token)访问并获取响应的数据。
    1. 购物车服务:用户用于处理待购买商品的服务,如:将商品添加到购物车、将商品从购物车删除、从购物车中结算部分或全部商品等
    2. 订单服务:用户用于下单、取消下单的服务

客户

  • 用于申请授权的网站、服务(或程序)等
    1. 用户使用某个微信小程序时,这个小程序就是客户。
    2. 用户使用 GitHub/Gitee 登录某个网站时,该网站就是客户。
    3. 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 IdentifierCSDN 在 微博 的 客户身份标识,即:用微博登陆 CSDN 时网址中的 client_id=2601122390
Redirect URICSDN 接收 微博 授权码的网址,即:用微博登陆 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)