互联网协议 — OAuth2 第三方授权协议

目录

OAuth

OAuth(Open Authorization,开放的授权协议)是一个安全的、开放而简易的用户资源授权协议。OAuth 协议有三大特征:

  1. 安全:不会使第三方触及到用户的帐号信息(如:用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 OAuth 是安全的。
  2. 开放:任何第三方都可以使用 OAuth 认证服务,任何服务提供商都可以实现自身的 OAuth 认证服务,因而 OAuth 是开放的。
  3. 简单:业界提供了 OAuth 的多种实现,如:PHP、JavaScript,Java,Ruby 等各种编程语言的开发包,大大节约了程序员的时间,因而 OAuth 是简易的。

互联网很多服务,如:Open API,很多大公司,如:Google,Yahoo,Microsoft 等都提供了 OAuth 认证服务。

OAuth 缘起

举一个典型案例:如果一个用户需要两项服务,图片在线存储服务 A、图片在线打印服务 B。假设服务 A、服务 B 由两家不同的服务提供商提供,所以用户需要在这两家服务提供商的网站上分别注册两个用户名、密码各不相同的账户。

当用户要使用服务 B 打印存储在服务 A 上的图片时,用户该如何处理?

  • 方式 1:用户先将图片从服务 A 下载到本地,然后上传到服务 B 上打印,这种方式安全但处理比较繁琐,效率低下;

  • 方式 2:用户将在服务 A 上注册的用户名与密码提供给服务 B,服务 B 使用用户的帐号到服务 A 处下载待打印的图片。这种方式的效率是提高了,但是安全性也大大降低了(服务 B 可以使用用户的用户名与密码去服务 A 上查看甚至篡改用户的资源)。

很多公司和个人都尝试解决此类问题,包括:Google、Yahoo、Microsoft,这也促进了 OAuth 项目组的产生。OAuth 最终由 Blaine Cook、Chris Messina、Larry Halff 及 David Recordon 共同发起,目的在于为 API 访问授权提供一个开放的标准。

OAuth 规范的 1.0 版于 2007 年 12 月 4 日发布与 IETF(国际互联网工程任务组),编号是 RFC5849,标志着 OAuth 正式成为互联网标准协议。

OAuth 原理

在这里插入图片描述

  • Client:第三方应用(Third-party application)客户端。
  • Resource Owner:资源所有者。
  • Authorization server:认证服务器,即服务提供商专门用来处理认证的服务器。
  • Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。

第三方应用登录流程:

  1. 用户打开第三方应用客户端以后,客户端要求用户给予授权。
  2. 用户同意给予客户端授权。
  3. 客户端使用上一步获得的授权,向认证服务器申请令牌。
  4. 认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
  5. 客户端使用令牌,向资源服务器申请获取资源。
  6. 资源服务器确认令牌无误,同意向客户端开放资源。

OAuth 在 Client 与 Resource server 之间设置了一个授权层(Authorization Layer)。Client 不能直接登录 Resource server,只能登录 Authorization server。上述步骤 2 是整个流程的关键,有了这个授权以后,客户端就可以获取令牌继而凭令牌获取资源。

令牌与密码的区别

令牌(token)与密码(password)都用于身份认证,但有三点差异:

  1. 令牌是短期的,到期会自动失效,用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。
  2. 令牌可以被数据所有者撤销,但篡改后会立即失效
  3. 令牌有权限范围(scope),对于网络服务来说,只读令牌就比读写令牌更安全。密码一般是完整权限。

OAuth2

OAuth2 是 OAuth1.0 的升级版本,但不向前兼容 OAuth1.0,即完全废止了 OAuth1.0。2012 年 10 月,OAuth 2.0 协议正式发布为 RFC 6749。当下百度开放平台,腾讯开放平台等大部分的开放平台都使用了 OAuth 2.0 协议。

OAuth2 的四种授权模式

  • 授权码(authorization-code)
  • 隐藏式(implicit)
  • 密码式(password):
  • 客户端凭证(client credentials)

授权码

授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。

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

举例说明:我作为一个用户在使用网站 A,并希望通过网站 A 直接访问 B 的资源,此时 B 会要求 A 提供我的用户信息,例如:弹出 QQ 账户的登录授权窗口。我把 QQ 账户登录成功后,表示我答应了 A 可以访问 B 中属于我自身的资源。我向 B 证明了合法的身份后,B 同时向 A 发放了一个令牌(Token),A 拿着这个 Token 就可以有限的时间内访问网站 B 中有限的资源。

在这里插入图片描述

隐藏式

有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。隐藏式授权,允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为 “授权码隐藏式(implicit)”。

这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。

在这里插入图片描述

密码式

如果你高度信任某个第三方应用,密码式授权允许用户把用户名和密码直接告诉该第三方应用。该应用就使用你的密码,申请令牌,这种方式称为 “密码式(password)”。

在这里插入图片描述

客户端凭证

凭证式授权指客户端以自己的名义,而不是以用户的名义,向 “服务提供商” 进行认证。严格地说,客户端模式并不属于 OAuth 协议所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求 “服务提供商” 提供服务,其实不存在授权问题。

所以,凭证式授权仅仅适用于没有前端的命令行应用,即在命令行下请求令牌。这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。

在这里插入图片描述

更新令牌

令牌的有效期到了,如果让用户重新走一遍上述的流程,用户体验必然不好。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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章