开放平台鉴权以及OAuth2.0介绍

摘要:
OAuth 2.0协议OAuth是一种开发标准,允许用户授权第三方网站或应用程序访问其存储在其他服务提供商上的信息,而无需向第三方站点提供用户名和密码或共享其数据内容。为了支持这些不同类型的第三方应用程序,OAuth2.0提出了以下四种授权类型:授权代码,适用于使用服务器的应用程序授权。资源所有者密码证书许可证,OAuth简化版,通常用于移动应用程序身份验证,称为xAuth。它用于第三方应用程序,以防止CSRF攻击。成功授权后,回调将按原样返回。

OAuth 2.0 协议

  • OAuth是一个开发标准,允许用户授权第三方网站或应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的内容。
  • OAuth 2.0不兼容1.0。

协议的参与者

  • RO (resource owner): 资源所有者,对资源具有授权能力的人。
  • RS (resource server): 资源服务器,它存储资源,并处理对资源的访问请求。
  • Client: 第三方应用,它获得RO的授权后便可以去访问RO的资源。
  • AS (authorization server): 授权服务器,它认证RO的身份,为RO提供授权审批流程,并最终颁发授权令牌(Access Token)。

授权方式

在开放授权中,第三方应用(Client)可能是一个Web站点,也可能是在浏览器中运行的一段JavaScript代码,还可能是安装在本地的一个应用程序。这些第三方应用都有各自的安全特性。对于Web站点来说,它与RO浏览器是分离的,它可以自己保存协议中的敏感数据,这些密钥可以不暴露给RO;对于JavaScript代码和本地安全的应用程序来说,它本来就运行在RO的浏览器中,RO是可以访问到Client在协议中的敏感数据。

OAuth2.0为了支持这些不同类型的第三方应用,提出了下面四种授权类型:

  1. 授权码 (Authorization Code Grant),适用于有server端的应用授权。
  2. 隐式授权 (Implicit Grant),适用于通过客户端访问的应用授权。
  3. 资源所有者密码凭证许可 (Resource Owner Password Credentials Grant),OAuth简化版,常用于移动应用认证,称为xAuth。
  4. 受保护资源的客户端授权 (Client Credentials Grant)。
流程Response Type(第一次请求)Grant Type(第二次请求)可带Refresh Token说明
授权码codeauthorization_code常规流程
Implicittoken-适用于纯JS程序
用户认证-password客户端高度可信,且授权码流程不方便实施
客户端-client_credentials客户端高度可信,拥有被操作资源(自用型),或操作非敏感资源

Authorization Code 授权

1. 授权场景

Authorization code 授权适用于PC,无线客户端等需要和第三方server进行交互的应用场景。使用Authorization code授权,第三方能够集中处理用户的授权请求和授权结果,适用于有server端的应用。

2. 授权流程

Authorization code授权模式分为两步,首先获取authorization code,然后用code获取acces token。

示意图:

复制代码
     +----------+
     | Resource |
     |   Owner  |
     |          |
     +----------+
          ^
          |
         (B)
     +----|-----+          Client Identifier      +---------------+
     |         -+----(A)-- & Redirection URI ---->|               |
     |  User-   |                                 | Authorization |
     |  Agent  -+----(B)-- User authenticates --->|     Server    |
     |          |                                 |               |
     |         -+----(C)-- Authorization Code ---<|               |
     +-|----|---+                                 +---------------+
       |    |                                         ^      v
      (A)  (C)                                        |      |
       |    |                                         |      |
       ^    v                                         |      |
     +---------+                                      |      |
     |         |>---(D)-- Authorization Code ---------'      |
     |  Client |          & Redirection URI                  |
     |         |                                             |
     |         |<---(E)----- Access Token -------------------'
     +---------+       (w/ Optional Refresh Token)
复制代码

交互图:

  
复制代码
  +--------+                                           +---------------+
  |        |--(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        +---------------+
复制代码
3. 过程详解

1、获取Authorization Code

请求参数

  • client_id 必须 分配给应用的appid
  • redirect_uri 必须 授权回调地址,必须和应用注册的地址一致
  • response_type 必须 授权类型,此值固定为“code”
  • state 必须 client端的状态值。用于第三方应用防止CSRF攻击,成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
  • scope 可选 授予权限范围
  • 其他参数

如果用户成功授权,则会跳转到指定的回调地址,并在redirect_uri地址后带上Authorization Code和原始的state值

2、通过Authorization Code获取Access Token

请求参数

  • client_id 必须 分配给应用的appid
  • grant_type 必须 授权类型,此值为:authorization_code
  • client_secret 必须 分配给应用的secret
  • state 必须 client端的状态值。用于第三方应用防止CSRF攻击,成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
  • redirect_uri 必须 与上面一步中传入的redirect_uri保持一致
  • code 必须 上一步返回的Authorization Code值(必须设定此code的有效时间)

返回参数

  • access_token 必须 授权令牌
  • expires_in 必须 该access_token的有效期
  • refresh_token 可选 在授权自动续期步骤中,获取新的Access_Token时需要提供的参数
  • 其他参数 可选

3、[可选] 权限自动续期,获取access_token

Access_token一般需要根据应用特性设定有效期,过期后需要用户重新授权或采用自动续期的方式。

请求参数

  • grant_type 必须 授权类型,在本步骤中,此值为“refresh_token”
  • client_id 必须 分配给应用的appid
  • refresh_token 必须 第二步返回的refresh_token
  • client_secret 必须 分配给应用的secret

如果授权成功,则会返回和步骤二同样的结果。

Implicit 授权

1. 授权场景

Implicit授权一般适用于没有server端的客户端应用,由客户端发起授权请求,保存和处理access_token,但有些应用(如web应用等)为了提高用户体验,简化授权过程,也会常采用Implicit授权方式(注意,这种授权方式没有返回refresh_token。)

2. 授权流程

示意图:

复制代码
     +----------+
     | Resource |
     |  Owner   |
     |          |
     +----------+
          ^
          |
         (B)
     +----|-----+          Client Identifier     +---------------+
     |         -+----(A)-- & Redirection URI --->|               |
     |  User-   |                                | Authorization |
     |  Agent  -|----(B)-- User authenticates -->|     Server    |
     |          |                                |               |
     |          |<---(C)--- Redirection URI ----<|               |
     |          |          with Access Token     +---------------+
     |          |            in Fragment
     |          |                                +---------------+
     |          |----(D)--- Redirection URI ---->|   Web-Hosted  |
     |          |          without Fragment      |     Client    |
     |          |                                |    Resource   |
     |     (F)  |<---(E)------- Script ---------<|               |
     |          |                                +---------------+
     +-|--------+
       |    |
      (A)  (G) Access Token
       |    |
       ^    v
     +---------+
     |         |
     |  Client |
     |         |
     +---------+

   Note: The lines illustrating steps (A) and (B) are broken into two
   parts as they pass through the user-agent.
复制代码

交互图:

 
复制代码
     +----------+
     | Resource |
     |  Owner   |
     |          |
     +----------+
          v
          |    Resource Owner
         (A) Password Credentials
          |
          v
     +---------+                                  +---------------+
     |         |>--(B)---- Resource Owner ------->|               |
     |         |         Password Credentials     | Authorization |
     | Client  |                                  |     Server    |
     |         |<--(C)---- Access Token ---------<|               |
     |         |    (w/ Optional Refresh Token)   |               |
     +---------+                                  +---------------+
复制代码

交互图:

3. 过程详解

请求参数

  • response_type 必须 授权类型,在本步骤中,此值为“token”
  • client_id 必须 分配给应用的appid
  • redirect_uri 必须 授权回调地址,必须和应用注册的地址一致
  • scope 可选 授予权限范围
  • state 必须 client端的状态值。用于第三方应用防止CSRF攻击,成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
  • 其他参数 可选

如果成功授权,则会跳转到redirect_uri指定的回调地址,并带上access_token、expires_in、state以及与应用相关的参数。注意,这种授权方式没有返回refresh_token。

Resource Owner Password Credentials

该授权方式获取access token一般只有一步,类似如下GET/POST请求:https://open.xxx.com/oauth2/access_token?client_id=xxxx&client_secret=xxxxx&grant_type=password&username=xxx&password=xxx

OAuth2.0新特性

  • 服务器角色区分:授权服务器和资源服务器
  • 区别不同的用户类型、授权场景和授权流程
  • 将token分为频繁传输使用但是有效时长较短的Access Token和用于更新Access Token的Refresh Token
  • 定义多种token,降低资源请求的构造难度
  • 授权过程不签名,可根据需要采用HTTPS加密传输、验证客户端密钥(通过签名)、客户端注册时预先指定callback地址等手段。
  • 明确引入客户端注册流程:确定Client Type、callback URL以及其它信息
  • 引入可选的state参数,帮助客户端防范CSRF和管理状态
  • 引入scope参数,可以进行授权范围控制
  • token type等可被扩展: bearer(HTTPS), mac(HTTP+sign), etc.

淘宝的OAuth2.0安全控制

  • 只支持HTTPS(bears),不支持签名(签名是走以前老的授权方式)
  • 授权过程指定的callback URL必须与注册的callback URL在同一个域名,或者为um:ietf:wg:oauth:2.0:oob(表示只显示授权码,不回调callback URL)
  • 接口分不同级别(R1, R2, W1, W2),同一Token对不同级别接口有不同的有效期
  • 接口权限划分(item, promotion, user, etc.)

说明 为何引入authorization_code?

协议设计中,为什么要使用authorization_code来交换access_token?这是读者容易想到的一个问题。也就是说,在协议的第3步,为什么不直接将access_token通过重定向方式返回给Client呢?比如:

HTTP/1.1 302
Location:
https://www.facebook.com/?access_token=ya29.AHES6ZSXVKYTW2VAGZtnMjD&token_type=Bearer&expires_in=3600

如果直接返回access_token,协议将变得更加简洁,而且少一次Client与AS之间的交互,性能也更优。那为何不这么设计呢?协议文档[1]中并没有给出这样设计的理由,但也不难分析:(1) 浏览器的redirect_uri是一个不安全信道,此方式不适合于传递敏感数据(如access_token)。因为uri可能通过HTTP referrer被传递给其它恶意站点,也可能存在于浏览器cacher或log文件中,这就给攻击者盗取access_token带来了很多机会。另外,此协议也不应该假设RO用户代理的行为是可信赖的,因为RO的浏览器可能早已被攻击者植入了跨站脚本用来监听access_token。因此,access_token通过RO的用户代理传递给Client,会显著扩大access_token被泄露的风险。 但authorization_code可以通过redirect_uri方式来传递,是因为authorization_code并不像access_token一样敏感。即使authorization_code被泄露,攻击者也无法直接拿到access_token,因为拿authorization_code去交换access_token是需要验证Client的真实身份。也就是说,除了Client之外,其他人拿authorization_code是没有用的。 此外,access_token应该只颁发给Client使用,其他任何主体(包括RO)都不应该获取access_token。协议的设计应能保证Client是唯一有能力获取access_token的主体。引入authorization_code之后,便可以保证Client是access_token的唯一持有人。当然,Client也是唯一的有义务需要保护access_token不被泄露。 (2) 引入authorization_code还会带来如下的好处。由于协议需要验证Client的身份,如果不引入authorization_code,这个Client的身份认证只能通过第1步的redirect_uri来传递。同样由于redirect_uri是一个不安全信道,这就额外要求Client必须使用数字签名技术来进行身份认证,而不能用简单的密码或口令认证方式。引入authorization_code之后,AS可以直接对Client进行身份认证(见步骤4和5),而且可以支持任意的Client认证方式(比如,简单地直接将Client端密钥发送给AS)。 在我们理解了上述安全性考虑之后,读者也许会有豁然开朗的感觉,懂得了引入authorization_code的妙处。那么,是不是一定要引入authorization_code才能解决这些安全问题呢?当然不是。笔者将会在另一篇博文给出一个直接返回access_token的扩展授权类型解决方案,它在满足相同安全性的条件下,使协议更简洁,交互次数更少。

 
********转载:https://www.cnblogs.com/duanxz/p/4369738.html

免责声明:文章转载自《开放平台鉴权以及OAuth2.0介绍》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Spring SPI 机制总结百度云服务器与域名绑定,设置解析记录下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

电脑网络诊断显示Win10无法与设备或资源(DNS)通信解决办法

最近是做多错多还是人有点儿衰神附体,软件,电脑系统,各种问题层出不穷,今天早上打开电脑发现不少软件都无法联网,神马百度商桥,腾讯浏览器,百度云。。。昨天百度商桥打不开还以为是软件出了问题,因为火狐浏览器可以上网,qq可以上网、微信可以上网,这种部分软件无法联网的事情还是第一次发生。今天把软件卸载重装,电脑重启,重复了n遍之后终于意识到不是软件的问题了,于是就...

Windows10 切换用户访问共享

前言 Windows 对于访问共享文件夹的用户管理策略——是这样的: 第一次访问需要登录的共享文件夹:输入用户名、密码。 第一次 以后 访问同一的共享文件夹:默认上次使用的用户名、密码。 所以会出现无法切换用户登录的情况。 本文就此问题提供解决方法。 问题举例 找不到切换用户的入口 右键共享文件夹 “映射网络驱动器” 使用其他账户登录时: “网络文...

Unity之Bmob云存储一

无论我们做软件还是做游戏,少不了的就是和数据打交道,对于要保存到本地的数据,我们可以采用的载体太多了。例如:txt,Xml,Sqlite,SqlServer,Mysql等等,具体使用什么那就视情况而定了。但是假如我们要在游戏中要做一个在线排行榜,我们会怎么解决呢?有些人立刻会想到把数据放到服务器上不就OK了!对的,我也是这么想的!实践才是检验真理的唯一标准...

Windows虚拟器的安装与使用

前言 先说:你们要的东西我会放在文中和文章末尾,拿文件记得点赞,一手交钱一手交货 马上初中朋友们就要开始上网课了哎!(博主也是一位初中生) 有人可能会受网课的影响而不能……, 所以各路神仙研究出了各种方法。 其中一种就是安装虚拟机。(最复杂的办法) 其实虚拟机也不仅仅只有这一点作用,他可以……(自己想) 今天我就来说一下在windows系统下安装与使用虚拟...

win7下安装 oracle 10g:permission denied

  昨天换了win7系统,在装数据库oracle 10g,开始安装的时候蛮好的,但是在创建数据库过程中始终出现这个错误::ora-12546 tns permission denied。退出来在database configuration assistant在配置数据库也是这个错误。这个问题一直困扰着我,不过我安装多少遍都是这个错误。没办法在网上查找资料...

微信定时获取token

为了使第三方开发者能够为用户提供更多更有价值的个性化服务,微信公众平台开放了许多接口,包括自定义菜单接口、客服接口、获取用户信息接口、用户分组接口、群发接口等,开发者在调用这些接口时,都需要传入一个相同的参数access_token,它是公众账号的全局唯一票据,它是接口访问凭证。 access_token的有效期是7200秒(两小时),在有效期内,可以一直...