Total Pageviews

Tuesday, 13 September 2016

OAuth2.0中的关键概念解释

一、角色                                                                                                                            

OAuth定义了四种角色:

1、resource owner资源所有者

可以获得授权去访问受保护的资源的实体。这句很绕口,简单来说就是资源的所有者,这个所有者是指当初上传或生成的那个所有者,并不是指服务器的所有者。比如,anykoro在新浪微博中发了一篇微博,这个时候anykoro是resource owner,这篇微博就是resource

2、resource server资源服务器

承载受保护资源的服务器,可以接收和响应使用access token(访问令牌)请求受保护资源。
我们继续前面的例子,这里新浪微博的服务器就是resource server,它提供了可以通过access token获取anykoro所发微博的功能。如果不能提供这个功能,那么当然也就称不上resource server。

3、client客户

一个产生受保护资源请求的应用,该应用代表resource owner,并且已经获得其授权。所以其实客户就是指前面说到的这种特性的应用,是种application。还是继续前面的例子,现在anykoro在xxx网站,使用新浪微博账号登陆。此时这个xxx网站就是client。anykoro是resource owner,请求资源的服务器就是resource server。这里将这三个一起做总结,主要是因为,为了便于理解。

4、authorization server授权服务器

用来分发access token的服务器,主要分发给client,反过来说,就是client会向authorization server请求access token。当client获得access token后,才能说已经验证了resource owner,并且已经获得其授权。
这个部分对应什么?比如,anykoro使用新浪账号登陆时,会出现类似下图的情况,

点击授权后,client就获得了authorization code。
注意:现在来让用户做授权与否操作的,可不是authorization server!!!
真正的authorization server是给client用的,anykoro是看不到的。

二、协议流                                                                                                                            

接下来让我们看一张图,来更好的理解四种角色间的交互作用

     +--------+                               +---------------+
     |        |--(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
上图代表了整个协议流程的抽象图。它展示了整个流程,以及四个角色的作用,接下来我逐条解释
在过程开始前,我们默认用户已经点击了使用OAuth登陆,比如点击了新浪微博账号登陆按钮,

(A)过程:client(就是application)向resource owner请求授权。可以直接向resource owner请求,但更好的是通过authorization server作为中间物间接获得。
对应:client带着owner前往sina微博的授权页面,如果owner点击授权,则表示允许授权,就会有下面的B过程。(如果owner没有登录,会有提示用户输入用户名和密码的过程)

(B)过程:client获得了resource owner的授权认可(authorization grant),此授权认可是四种标准授权认可类型中的一种,也可以是其中一种的扩展类型(具体的可见下授权认可部分)。获得的授权认可的类型由client请求授权所使用的函数和authorization server支持的类型决定。
对应:跳转回client所在的网站,这个地址往往是client设定的。比如新浪微博登陆,你点击授权后,通常会回到登陆网站的某个特定页面。此时网站会获得authorization code。通常owner是不知道的。对owner来说,他只是同意授权给client,然后返回了client。

(C)过程:client提供授权认可,以请求一个access token,该token是可以被authorization server验证的,当然,也是由authorization server提供的。
对应:这部分对owner来说也是不知道的。C过程往往是和B过程在同一处代码中的。一般采用模拟的登录的方式,client在后台直接使用authorization code向authorization server请求access token。

(D)过程:authorization server验证client,并且核实授权认可,如果是有效,就发放access token。注意这里是两个验证,1验证client是不是被承认的(在新浪微博api中获得的APPkey等就是用于这个的),2验证resource owner是不是真的授权了(验证authorization grant),防止其他网站窃取authorization grant使用。只有在都通过验证后,才会发放给client,access token。
对应:新浪微博的验证服务器,当接收到client的请求后,验证下,通过了就发放access token

(E)过程:clent提供access token给resource server验证,判断此client是否可以获取受保护的资源。
对应:比如,owner在client上进行发布新的微博,此时client就会携带owner要发的内容和access token等主要的信息,发送给新浪微博。又或者client获取owner的最新微博,就直接携带access token,owner的用户名等主要信息,向新浪微博请求。

(F)过程:resource server核实access token,如果有效则响应请求。
对应:当新浪微博收到请求后,验证这个access token是否有效,有效的话,就完成client请求的操作。

总结:
两个验证点:
1、authorization server:验证client是否有资格(比如有sina微博appkey等);验证owner是否真授权,也即验证authorization grant有效性
2、resource server:验证client是否提供了有效的access token
3、整个过程对于新浪微博来说,它首先验证了用户的合法性,合法则同意用户的授权请求(返回authorization grant);然后验证获得用户授权的网站是否已通过了它的认证(返回access token);最后网站拿着access token可以请求用户的资源了。所以里面有两个身份验证。

三、Authorization Grant授权认可                                                                                                          

授权认可是一种凭证,代表resource owner已授权你(client)可访问其受保护的资源。将授权认可提供给authorization server,可以获取access token,当然前提client本身有资格。这里有四种基本的认可类型:

→授权码(authorization code)

→隐式(implicit)

→用户密码(resource owner password credentials)

→应用凭证(client credentials)

 你也可以给予以上的四种,自己扩展新的类型。

1、authorization code授权码(主流的使用方式)

当使用authorization server作为client和resource owne之间的中间物时,会用到授权码。用来代替直接向resource owner直接请求授权,client会将resource owner指向一台authorization server,在authorization server所提供的页面上,完成相应操作后,authorization server会将resource owner指引回client,并且返回的还有authorization code。

在指引resource owner返回client并带有authorization code之前,authorization server会验证resource owner并获得授权(注意这里获得授权的是authorization server)。因为resource owner只是向authorization server进行授权,所以resource owner的凭证是不会共享给client的。

authorization code提供了一些重要的安全信息,比如授权给client的行为,access token的传输。

这里的access token传输是指,直接传给client,而不通过resource owner的user-agent(比如浏览器)暴露给他人,包括resource owner本人。简单说来就是直接给client,不会再给resource owner,access token。

实例场景:

接下来,我们模拟一个应用场景。现在你的应用,需要整合新浪微博API,现在假设已经整合完成了。对于用户来说他的使用时如下流程,

点击使用新浪微博账号登陆-》跳转到新浪微博的一个验证页面(authorization server)-》在登陆完成后直接返回client的页面并传给client相应的authorization code(HTTP header实现)-》client可以在此authorization code中获取access token。

2、Implicit隐式

隐式授权是一个简化了的authorization code处理流程,该流程是为应用(client)能在浏览器中使用脚本语言(比如JavaScript)实现类似authorization code处理流程而特地优化的。在隐式处理流程中,authorization server不会向client发放authorization code,而是直接发放access token(以此作为resource owner授权的结果)。此类型的授权是隐性的,不会分发中间物凭证(eg.authorization code),并且会用于获取access token。

当分发一个隐式授权时,authorization server不会验证client。在某些情况,client身份可以通过跳转URI去验证,该跳转URI是用于向client传递access token。获得的access token会暴露给resource owner或其他可以访问resource owner的User-agent的应用。

隐式授权改进了响应性和一些client的效率(比如client是一个浏览器应用),这是由于其减少了为获得access token而进行的交互次数。但也会带来安全性上的问题,所以可以使用authorization code的时候,是使用哪种要好好权衡。

3、Resource Owner Password Credentials用户密码凭证

用户密码凭证(比如用户名和密码)可以直接使用,作为一种授权类型去获得access token。只有在高度信任resource owner和client的时候,才应该采用凭证。(比如,设备操作系统或高特权应用),还有当其他授权认可类型(比如authorization code)不可用时才使用。

尽管此类授权类型会指引client访问resource owner凭证,但resource owner凭证被用于一次请求并且用于交换access token。此授权类型可以消除因client希望以后使用而去保存resource owner凭证的需求,这是因为通过使用一个长期有效的access token(或者刷新access token)就可以去交换凭证 。

4、Client Credentials应用凭证

当授权范围限制在client控制下的受保护资源或是先前使用authorization server处理过的受保护资源时,client credentials应用凭证(或其他形式的client验证)可以用作授权认证。应用凭证用作认证授权的典型情况是,当client代表自己的时候(即,client就是resource owner),或请求访问基于(先前由authorization server处理过的)授权的受保护资源。

四、Access Token访问令牌                                                                                                      

access token是一种用于获取受保护资源的凭证,它是一条字符串,该字符串代表authorization server分发给client的授权。对于client来说此字符串是透明的。访问令牌根据resource owner的指示,指定了client访问的范围和时效,并可以被resource server和authorization server使用(也可以认为是需要用到,帮助验证)。

令牌将作为一个标示符,用作获取授权信息,或自己就以某种惯例或形式包含授权信息(比如,令牌字符串由一些数据和一个签名组成)。

访问令牌提供了一个抽象层,通过使用resource server可以理解的单个token去代替不同的授权结构(比如,用户名和密码)。此抽象使得分发访问令牌比用于获得令牌的授权认可有更大的限制,同时也不需要resource server理解不同的验证方法。

根据resource server安全需要,访问令牌可以有不同的格式,结构,和工具方法(比如加密属性)。

五、Refresh Token可刷新令牌                                                                                                      

可刷新令牌是用于获得访问令牌的凭证。可刷新令牌是由authorization server分发的,当前访问令牌失效时,可刷新令牌可以用于获得一个新的访问令牌或得到一个相同使用范围(或更小)的附加访问令牌。(访问令牌可能比resource owner的授权,有更少的生存时间和权限,可以认为是小于等于关系)。分发可刷新令牌是可选的,如果authorization server分发可刷新令牌,那么当分发access token的时候就会将可刷新令牌包括进去。

可刷新令牌是一个字符串,代表resource owner对client的授权。该字符串对client是透明的。令牌代表一个标示符,用于接收授权信息。与访问令牌不同的是,可刷新令牌只被用于authorization server,而不会发送给resource server。发送给resource server的始终是access 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        +---------------+

               Figure 2: Refreshing an Expired Access Token
该流程图包括以下步骤:

(A):client访问authorization server进行验证,通过提供提供授权认可,以请求access token。

(B):authorization server验证client,并且验证授权认可(四种类型中的一种),如果有效则分发一个访问令牌和一个可刷新令牌

(C):通过提供access token,client可向resource server请求受保护资源

(D):resource server验证访问令牌,如果有效,就响应请求

(E): 步骤(C)和(D)重复进行,直到访问令牌过期。如果client知道访问令牌过期,就直接跳到步骤(G),否则它还会请求受保护资源。

(F):由于访问令牌失效,resource server返回无效令牌错误。

(G):client请求一个新的访问令牌,通过向authorization server提供可刷新令牌并进行验证。对client的验证条件是基于client的类型和authorization server的策略。

(H):authorization server验证client和可刷新令牌,如果有效就分发一个新的访问令牌(你也可以再发送一个新的可刷新令牌)