OAUTH开放授权

OAUTH开放授权为用户资源的授权提供了一个安全的、开放而又简易的标准。OAUTH的授权不会使第三方触及到用户的帐号信息例如用户名与密码等,即第三方无需使用用户的用户名与密码就可以申请获得该用户在OAUTH提供方资源的授权,因此OAUTH授权是安全的,目前OAUTH的版本为2.0

实例

假如此时有一个网站提供照片的冲印服务并且提供邮递服务,但是用户的所有照片都存储在Google网盘中,此用户如果想冲印大量照片,那么有以下几种解决方案:

  • 登录用户自己的Google账号,将所有需要打印的照片下载到本地,然后上传照片到云冲印网站,交予网站任务让其帮你冲印。这种解决方案是可行的,但是需要将照片下载后再上传,比较麻烦。
  • 将自己的Google账号密码告知冲印网站,然后冲印网站读取照片,此后用户选择读取的照片再交予网站进行打印服务。这种解决方案非常不可靠,冲印网站此时能够接触到用户的账号与密码,不排除其在后端服务器保存账号密码的可能。冲印网站只是需要读取照片数据,而此时冲印网站有了跟用户一样的权力,对于Google账号中保存的数据全部可以获取到,扩大了冲印网站的权力。假如所有的需要Google授权的网站都是以告知账号密码的形式进行授权,用户若想收回对于这个网站的授权,只能通过修改密码的方式,而此时所有的对于其他网站的授权将全部失效。若是授权网站以明文的形式记录了用户授权的网站的账号与密码,一旦数据库被攻陷,那么用户信息就将全部泄露。此外不排除网站进行钓鱼欺骗用户账号密码的嫌疑,实际上通过赠送物品而骗取用户账号密码是钓鱼网站常用的手段。
  • 使用OAUTH开放授权,通过用户授权照片冲印网站能够获得的数据范围,而对于其他的数据则不给予其访问权限,用户的授权行为全部在Google的授权网站中进行,即使用户在授权时未登录Google需要账号密码登录时也是在Google官方网站进行,冲印网站无法得到用户账号与密码,当用户在Google授权页面将读取照片的权限给予冲印网站后,冲印网站便可读取照片信息然后进行冲印服务。简单来说OAuth就是一种授权机制,数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据,系统从而产生一个短期的进入令牌token,用来代替密码,供第三方应用获取资源使用。

授权过程

名词定义

  • Third-party application:第三方应用程序,例如上文中的云冲印网站。
  • HTTP service: 服务提供商,例如上文中的Google
  • User Agent: 用户代理,一般都是使用浏览器。
  • Authorization server: 认证服务器,服务提供商用来处理认证的服务器。
  • Resource server: 资源服务器,即服务提供商存放用户资源的服务器。

基本流程

  • 用户打开应用程序,应用程序要求用户给予授权。
  • 用户在服务提供商网站允许授权,返回应用程序授权信息。
  • 应用程序使用获得的授权,向认证服务器请求令牌Token
  • 认证服务器对于应用程序的授权码等信息进行确认,认证无误后发放令牌。
  • 应用程序使用令牌向资源服务器请求资源。
  • 资源服务器确认令牌无误后,同意向应用程序开放资源。

客户端授权模式

在基本流程的第二步应用程序需要获取用户的授权信息,进而才能获取令牌,OAuth 2.0定义了四种授权方式。

授权码模式

授权码模式authorization code是功能最完整、流程最严密的授权模式,也是最常用的授权模式,它的特点就是通过客户端的后台服务器与服务提供商的认证服务器进行互动,避免了令牌Token在前端传输,前端只传递一个授权码,而授权码需要结合AppidAppSecret等信息在后端与认证服务器交换令牌Token,而AppSecret此类数据需要严格保密,所以仅由CODE不能直接获取到令牌,授权码模式安全性非常高。

  • 用户打开应用程序,点击第三方授权按钮,此时需要传递应用程序的APPID以及授权后跳转的URL地址,页面跳转到授权网站,或者打开一个新的窗口到授权网站,本例主要是以跳转到授权网站为例,但基本流程相同。
  • 用户在授权网站点击授权按钮,此时浏览器跳转到上一部传递的URL地址并且携带授权码CODE信息,这个授权码信息一般有效期比较短,一般为10分钟。
  • 应用程序收到授权码,将授权码CODE发送到后端,后端根据授权码CODE以及AppidAppSecret等信息在后端对认证服务器发起请求。
  • 认证服务器检查请求的数据是否正确,检查正确后返回令牌Token
  • 应用程序使用令牌向资源服务器请求资源,资源服务器确认令牌无误后,同意向应用程序开放资源。

简化模式

简化模式implicit grant type不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了授权码这个步骤。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。

  • 用户打开应用程序,点击第三方授权按钮,此时需要传递应用程序的APPID以及授权后跳转的URL地址,页面跳转到授权网站,或者打开一个新的窗口到授权网站,本例主要是以跳转到授权网站为例,但基本流程相同。
  • 用户在授权网站点击授权按钮,此时浏览器跳转到上一部传递的URL地址并且携带一个HASH信息,其中包含了令牌。
  • 浏览器向资源服务器发起请求,此时不携带上一步请求的HASH信息,资源服务器返回一个解析脚本。
  • 浏览器解析上一步获取的脚本,然后通过脚本解析出HASH中的令牌,此时应用程序获取了令牌。
  • 应用程序使用令牌向资源服务器请求资源,资源服务器确认令牌无误后,同意向应用程序开放资源。

密码模式

密码模式Resource Owner Password Credentials Grant中,用户向客户端提供自己的用户名和密码,客户端使用这些信息,向服务商提供商索要授权。在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码,这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。

  • 用户向应用程序提供用户名与密码,应用程序使用账号与密码发给认证服务器,请求令牌。
  • 认证服务器确认信息无误后,返回令牌给应用程序。
  • 应用程序使用令牌向资源服务器请求资源,资源服务器确认令牌无误后,同意向应用程序开放资源。

客户端模式

客户端模式Client Credentials Grant指客户端以自己的名义,而不是以用户的名义,向服务提供商进行认证。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求服务提供商提供服务,严格来说这种模式其实并不存在授权问题。

  • 用户在应用程序中注册身份,应用程序向认证服务器进行身份认证并请求令牌。
  • 认证服务器确认身份无误后,返回令牌给应用程序。
  • 应用程序使用令牌向资源服务器请求资源,资源服务器确认令牌无误后,同意向应用程序开放资源。

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

https://zhuanlan.zhihu.com/p/138424479 http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html http://www.ruanyifeng.com/blog/2019/04/oauth_design.html