前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OAuth2.0协议详解

OAuth2.0协议详解

作者头像
山行AI
发布2019-06-28 12:07:14
1.4K0
发布2019-06-28 12:07:14
举报
文章被收录于专栏:山行AI山行AI山行AI

1. RFC 5849上对OAuth2.0的介绍:

The OAuth 2.0 authorization framework enables a third-party
   application to obtain limited access to an HTTP service, either on
   behalf of a resource owner by orchestrating an approval interaction
   between the resource owner and the HTTP service, or by allowing the
   third-party application to obtain access on its own behalf.  This
   specification replaces and obsoletes the OAuth 1.0 protocol described
   in RFC 5849.

更多可以访问:https://tools.ietf.org/html/rfc6749

2. 应用场景

主要用于第三方登录的场景。比如A平台上的用户U要去B平台上读取该用户的一些信息,这时候A平台需要获取用户允许读取B平台上信息的授权。如果直接让用户输入 B平台的登录用户名和密码,那么A平台为了用户后续的操作,会保存用户的密码,而且当像A平台这样的第三方平台比较多的时候,这种操作就变得相当不安全。这就是 OAuth该发挥作用的场景了。

3. 几个概念

  1. Resource Owner:资源所有者,用户
  2. Authorization server:认证服务器,服务提供商(B平台)用来处理认证的server
  3. Resource Server:资源服务器,服务提供商(B平台)用来存放用户生成的资源的服务器,与认证服务器可以相同也可以不同

4. OAuth协议处理流程

   +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+

                     Figure 1: Abstract Protocol Flow
  • (A) 用户访问第三方应用程序(简称:客户端)以后,客户端要求用户给予授权。
  • (B) 用户同意给予客户端授权。
  • (C) 客户端使用第 2 步获得的授权,向认证服务器申请令牌(Access Token)。
  • (D) 认证服务器对客户端进行认证以后,确认无误,同意发放令牌(Access Token)。
  • (E) 认证服务器对客户端进行认证以后,确认无误,同意发放令牌(Access Token)。
  • (F) 认证服务器对客户端进行认证以后,确认无误,同意发放令牌(Access Token)。

5. 授权方式

5.1 授权码方式(Authorization Code)

这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。

  1. 第一步,A 网站提供一个链接,用户点击后就会跳转到 B 网站,授权用户数据给 A 网站使用。下面就是 A 网站跳转 B 网站的一个示意链接。
https://graph.qq.com/oauth2.0/show?which=Login&display=pc&
response_type=code&client_id=101484447
&redirect_uri=https%3A%2F%2Fna.abc.cn%2Fsign%2Foauth%2Fcallback
&scope=get_user_info&state=state

上面B网站为腾讯qq,做过三方登录的应该都会比较熟悉。 url里面的response_type参数为code表示要求返回授权码,client_id是标识第三方应用的,redirect_uri参数是 B 接受或拒绝请求后的跳转网址,scope参数表示要求的授权范围

  1. 第二步会弹出qq的登录界面,如果已经登录则会出现一个已登录用户的图标,登录或点击已登录图标进行授权后,会跳转到redirect_uri指定的网址,并且会传回一个授权码。
https://na.abc.cn/sign/oauth/callback?code=4443C02228E47694BEDA&state=state

上面这个code就是授权码,一般这个回调地址对应的是A平台后台服务的接口。

  1. 这时A平台就可以在后台通过授权码去B平台(这里是qq)请求access token即令牌。
https://b.com/oauth/token?
 client_id=CLIENT_ID&
 client_secret=CLIENT_SECRET&
 grant_type=authorization_code&
 code=AUTHORIZATION_CODE&
 redirect_uri=CALLBACK_URL
  • client_id参数和 client_secret参数用来让 B 确认 A 的身份( client_secret参数是保密的,因此只能在后端发请求);
  • grant_type参数的值是 AUTHORIZATION_CODE,表示采用的授权方式是授权码;
  • code参数是上一步拿到的授权码;
  • redirect_uri参数是令牌颁发后的回调网址。这里的redirect_uri一般对应的是后台接口地址,用于接收令牌。

注:qq登录时在这里是没有redirect_uri这一项的,它是直接在响应中返回令牌信息的。然后在后台可以通过这个access token去qq请求用户信息,union id和open id等。

  1. B 网站收到请求以后,就会颁发令牌。具体做法是向 redirect_uri指定的网址,发送一段 JSON 数据:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{    
    "access_token":"ACCESS_TOKEN",
    "token_type":"bearer",
    "expires_in":2592000,
    "refresh_token":"REFRESH_TOKEN",
    "scope":"read",
    "uid":100101,
    "info":{...}
}

一般对应的是A 网站的后台接口。注意:HTTP头信息中明确指定不得缓存。

5.2 隐藏式(implicit)

RFC 6749 就规定了第二种方式,允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)"隐藏式"(implicit)。

The implicit grant is a simplified authorization code flow optimized
   for clients implemented in a browser using a scripting language such
   as JavaScript.  In the implicit flow, instead of issuing the client
   an authorization code, the client is issued an access token directly
(as the result of the resource owner authorization).  The grant type
   is implicit, as no intermediate credentials (such as an authorization
   code) are issued (and later used to obtain an access token).

A网站请求:

https://b.com/oauth/authorize?
  response_type=token&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=read

B网站会跳转到redirect_url并带上令牌:

https://a.com/callback#token=ACCESS_TOKEN

注意,令牌的位置是 URL 锚点(fragment),而不是查询字符串(querystring),这是因为 OAuth 2.0 允许跳转网址是 HTTP 协议,因此存在"中间人攻击"的风险,而浏览器跳转时,锚点不会发到服务器,就减少了泄漏令牌的风险。 这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。

5.3 密码式(password)

The resource owner password credentials (i.e., username and password) can be used directly as an authorization grant to obtain an access token. The credentials should only be used when there is a high degree of trust between the resource owner and the client (e.g., the client is part of the device operating system or a highly privileged application), and when other authorization grant types are not available (such as an authorization code).

A网站请求:

https://oauth.b.com/token?
  grant_type=password&
  username=USERNAME&
  password=PASSWORD&
  client_id=CLIENT_ID

B网站直接在响应中获取到令牌。

5.4 凭证式(client credentials)

最后一种方式是凭证式(client credentials),适用于没有前端的命令行应用,即在命令行下请求令牌。 A网站请求:

https://oauth.b.com/token?
  grant_type=client_credentials&
  client_id=CLIENT_ID&
  client_secret=CLIENT_SECRET

grant_type参数等于client_credentials表示采用凭证式,client_id和client_secret用来让 B 确认 A 的身份。B网站验证通过后,直接返回令牌。这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。

6. 令牌的使用

A网站拿到令牌后,就可以携带令牌通过B网站的api接口向B网站的API请求数据了。具体做法是在请求的头信息,加上一个Authorization字段,令牌就放在这个字段里面。ACCESS_TOKEN就是拿到的令牌。

curl -H "Authorization: Bearer ACCESS_TOKEN" \
"https://api.b.com"

7. 更新令牌

用于更新accessToken的,令牌的有效期到了,如果让用户重新走一遍上面的流程,再申请一个新的令牌,很可能体验不好,而且也没有必要。OAuth 2.0 允许用户自动更新令牌。 具体方法是,B 网站颁发令牌的时候,一次性颁发两个令牌,一个用于获取数据,另一个用于获取新的令牌(refresh token 字段)。令牌到期前,用户使用 refresh token 发一个请求,去更新令牌。

https://b.com/oauth/token?
  grant_type=refresh_token&
  client_id=CLIENT_ID&
  client_secret=CLIENT_SECRET&
  refresh_token=REFRESH_TOKEN

grant_type参数为refresh_token表示要求更新令牌,client_id参数和client_secret参数用于确认身份,refresh_token参数就是用于更新令牌的令牌。B 网站验证通过以后,就会颁发新的令牌。

更新令牌流程图:

 +--------+                                           +---------------+
  |        |--(A)------- Authorization Grant --------->|               |
  |        |                                           |               |
  |        |<-(B)----------- Access Token -------------|               |
  |        |               & Refresh Token             |               |
  |        |                                           |               |
  |        |                            +----------+   |               |
  |        |--(C)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(D)- Protected Resource --| Resource |   | Authorization |
  | Client |                            |  Server  |   |     Server    |
  |        |--(E)---- Access Token ---->|          |   |               |
  |        |                            |          |   |               |
  |        |<-(F)- Invalid Token Error -|          |   |               |
  |        |                            +----------+   |               |
  |        |                                           |               |
  |        |--(G)----------- Refresh Token ----------->|               |
  |        |                                           |               |
  |        |<-(H)----------- Access Token -------------|               |
  +--------+           & Optional Refresh Token        +---------------+

               Figure 2: Refreshing an Expired Access Token

参考链接:

  1. https://tools.ietf.org/html/rfc6749
  2. http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html
  3. http://www.ruanyifeng.com/blog/2019/04/oauth_design.html
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开发架构二三事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. RFC 5849上对OAuth2.0的介绍:
  • 2. 应用场景
  • 3. 几个概念
  • 4. OAuth协议处理流程
  • 5. 授权方式
    • 5.1 授权码方式(Authorization Code)
      • 5.2 隐藏式(implicit)
        • 5.3 密码式(password)
          • 5.4 凭证式(client credentials)
          • 6. 令牌的使用
          • 7. 更新令牌
          相关产品与服务
          访问管理
          访问管理(Cloud Access Management,CAM)可以帮助您安全、便捷地管理对腾讯云服务和资源的访问。您可以使用CAM创建子用户、用户组和角色,并通过策略控制其访问范围。CAM支持用户和角色SSO能力,您可以根据具体管理场景针对性设置企业内用户和腾讯云的互通能力。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档