对OAuth2.0协议的理解和测试demo

1. 什么是OAuth

OAuth(开放受权)是一个开放标准,容许用户受权第三方网站访问他们存储在另外的服务提供者上的信息,而不须要将用户名和密码提供给第三方网站或分享他们数据的全部内容。
OAuth容许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每个令牌受权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth让用户能够受权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非全部内容。html

2. OAuth中的术语介绍

角色

OAuth定义了四个角色:git

  • 资源全部者(用户)
  • 资源服务器
  • 认证服务器(能够是与资源服务器相同的服务器)
  • 客户端(第三方应用)

用户

OAuth 2.0规范将用户称为“资源全部者”。资源全部者是授予其账户某些部分访问权限的人。在这种状况下,资源能够是数据(照片,文档,联系人),服务(发布博客条目,转移资金)或任何其余须要访问限制的资源。任何想要表明用户行事的系统必须首先得到他们的许可。github

资源服务器

资源服务器是包含第三方应用程序正在访问的用户信息的服务器。资源服务器必须可以接受并验证访问令牌,并在用户容许时授予请求。资源服务器不必定须要知道应用程序。json

认证服务器

认证服务器,处理用户的受权请求,以及给客户端(第三方用户)授予一个访问令牌(access_token)。所以,认证服务器一般具备两个主URL,一个用于受权请求,一个用于给客户端授予访问令牌。这些一般是这样的:服务器

客户端

客户端是试图表明用户行动或访问用户资源的应用程序。在客户端能够访问用户的账户以前,须要得到权限。微信

受权码

受权码是用于和认证服务器交换令牌使用的,在用户赞成受权请求后,认证服务器会返回一个受权码给客户端,而后客户端使用受权码和认证服务器交换访问令牌。app

访问令牌(access_token)

访问令牌是向资源服务器发出通过身份验证的请求时使用的字符串。字符串自己对使用它的应用程序没有意义,但表示用户已受权第三方应用程序访问其账户。令牌具备相应的访问持续时间,范围以及服务器所需的其余可能信息。客户端经过使用访问令牌向资源服务器获取指定的信息。ide

刷新令牌

刷新令牌是一个字符串,用于在访问令牌过时时获取新的访问令牌。并不是全部资源服务器都使用刷新令牌。网站

3. 协议运做流程

下面是OAuth2.0协议的运做流程图,图片来源:OAuth2.0协议草案V21的1.2节

上图描述了四个角色之间的互动,主要包括下面几个步骤:url

(A) 客户端向用户(资源拥有者)发出受权请求;

(B) 用户赞成受权请求;

(C) 客户端向认证服务器进行身份认证,并请求获取访问令牌;

(D) 认证服务器对客户端进行身份校验,若是有效,则发放令牌;

(E) 客户使用令牌向资源服务器获取受保护的资源;

(F) 资源服务器验证令牌,若是有效,则赞成客户端的资源访问请求

在步骤(B)中,用户要如何接受客户端的受权请求呢?OAuth2.0协议规定了四种受权类型:authorization code(受权码模式), implicit(简化模式), resource owner password credentials(密码模式), and client credentials(客户端模式)。它还提供了一种用于定义其余受权类型的扩展机制。这里我介绍下受权码模式。

4 authorization code(受权码模式)

下面是受权码模式的流程图,图片来源:OAuth2.0协议草案V21的4.1节

步骤说明:

(A) 客户端向认证服务器发出受权请求,并将用户导向认证服务器,其中 Client Identifier 表示客户端身份标识,Redirection URI 表示重定向uri;

(B) 认证服务器对资源全部者进行身份验证,并肯定资源全部者是否授予或拒绝客户端的访问请求;

(C) 假如用户赞成受权,那么认证服务器会重定向到(A)中指定的uri,并返回一个code(受权码);

(D) 客户端使用(C)中获取的受权码code向认证服务器交换令牌(token);

(E) 认证服务器对客户端的身份进行校验,好比说判断code是否有效,uri是否匹配等,若是经过则赞成发放令牌。

在上面(A)中的 Client IdentifierRedirection URI 是如何得到的呢?这里咱们以github为例,简单说明一下

假如说咱们要登录开源中国,在登陆界面咱们能够看到,它支持经过微信、QQ、github等帐号登录。若是咱们选择github帐号登录,那么开源中国就是客户端,github就是认证服务器,同时也是资源服务器。开源中国在使用OAuth2.0协议和github通讯前,首先要到github上面注册OAuth Apps,注册须要的信息包括Application name、Homepage URL、Application description和Authorization callback URL,注册成功后,github会提供client_id和client_secret,其中client_id就表示 Client IdentifierRedirection URI 就是注册时填写的Authorization callback URL。

下面是上面这些步骤所须要的参数。
(A)中,客户端申请认证的URI,包含如下参数:

  • response_type:表示受权类型,必选项,此处的值固定为"code"
  • client_id:表示客户端的ID,必选项
  • redirect_uri:表示重定向URI,可选项
  • scope:表示申请的权限范围,可选项
  • state:客户端用于维护请求和回调之间状态的不透明值。推荐使用

客户端可构造一个包含上述参数的uri,将用户导向认证服务器,例如:

GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com

(C)中,服务器回应客户端的URI,包含如下参数:

code:表示受权码,必选项。该码的有效期应该很短,一般设为10分钟,客户端只能使用该码一次,不然会被受权服务器拒绝。该码与客户端ID和重定向URI,是一
一对应关系。
state:若是客户端的请求中包含这个参数,认证服务器的回应也必须如出一辙包含这个参数。

一个成功的例子:

HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz

一个失败的例子:

HTTP/1.1 302 Found
Location: https://client.example.com/cb?error=access_denied&state=xyz

(D)中,客户端向认证服务器申请令牌的HTTP请求,包含如下参数:

grant_type:表示使用的受权模式,必选项,此处的值固定为"authorization_code"。
code:表示上一步得到的受权码,必选项。
redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。
client_id:表示客户端ID,必选项。

例如:

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded;charset=UTF-8

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

(E)中,认证服务器发送的HTTP回复,包含如下参数:

access_token:表示访问令牌,必选项。
token_type:表示令牌类型,该值大小写不敏感,必选项,能够是bearer类型或mac类型。
expires_in:表示过时时间,单位为秒。若是省略该参数,必须其余方式设置过时时间。
refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。
scope:表示权限范围,若是与客户端申请的范围一致,此项可省略。

一个成功的例子以下:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"bearer",
}

5. 模拟OAuth工做流程的demo

demo写的很简单,仅仅是为了帮助协议工做流程~
基于OAuth2.0协议,模拟客户端实现,代码下载地址
基于OAuth2.0协议,模拟服务端实现,代码下载地址
基于OAuth2.0协议,实现访问github的客户端,代码下载地址

参考网站:

相关文章
相关标签/搜索