It’s gangzz!

A blogging about coding and life..

Oauth2 Specification Client Registration

2. Client Registration

开始启动协议之前,Client要在权限服务器注册自己。通过何种方式注册超出了该协议讨论范围,当时通常是通过HTML页面和终端用户交互。

协议中不曾规定客户端的注册必须直接与权限服务器交互,只要权限服务器支持,注册可以通过任何方式以便建立可信的关系或者获取必要的客户端属性(比如重定向URL、客户端类型等)。比如注册可以通过自发布或者第三方发布的校验机制完成,或者是权限服务器使用可信的渠道发现客户端。

当注册一个客户端的时应该:

  1. 指明章节2.1中规定的客户端类型。
  2. 提供章节3.1.2中规定的重定向URL。
  3. 包含其他权限服务器要求的信息(应用名称、网站、描述、logo、接受的法律条款等)。

2.1 客户端类型

OAuth根据与权限服务器达成安全认证的能力,定义了两种客户端类型(比如保存它们客户端凭证机密性的能力)。

机密 客户端能够保证它们客户端凭证的机密性(比如客户端实现了严格限制凭证访问的安全服务器),或能通过其它途径保证它们授权的安全。

公共 客户端不能够保证凭证的机密性(客户端运行在资源拥有者的设备上,比如安装的本地应用或是浏览器应用),也没有其它途径保证安全。

权限服务器关于安全的定义和其可接受的客户端机密暴露级别决定了客户端的类型。权限服务器绝对不应该对客户端的类型有任何假设。

一个客户端(Client)可以是一组分布式的组件,每个组件有自己的客户端类型和安全环境(比如一个客户端保护一个基于服务器的机密组件和一个公共的浏览器客户端)。如果一个权限服务器不支持或者没有提供任何相关的指导,客户端应该分别注册自己的每个组件。

该协议是根据下面的各方面设计的:

  • web application(网络应用) 网络应用是一个机密的运行于服务器的应用。资源拥有者使用运行在其设备上的客户端(浏览器)通过HTML页面进行访问。发布给客户端的用户凭证和Access Token一样都保存在服务器端,对资源拥有者是不可见的。

  • user-agent-based application

客户端应用是从服务器下载并在资源拥有者所使用设备上的客户端(如浏览器)运行应用。协议和凭证数据能够轻易地被资源拥有者访问到。因为该类应用驻留在用户客户端(浏览器)中,它们能够很容易的利用容器的能力实现授权。

  • native application

本地应用是安装和运行在用户设备本地的应用。协议数据和凭证可以被资源拥有者访问到。一般假设应用中的任何授权信息都是可以被抽取的。另一方面,动态发布的凭证(access token和refresh token)可以在安全方面达到一定的可接受度。至少,可以抵御与该客户端交互的某些敌意的服务器。在一些平台上,可以防止同设备上其它应用的访问。

2.2 客户端身份(Id)

权限服务器发布给注册的客户端一个身份——一个代表了客户端信息的唯一字符串。这个身份不是加密的,它对资源拥有者是可见的,不能使用这个Id进行授权。客户端Id在一个权限服务器中是唯一的。

该协议并未规定Id的长度,客户端不应该猜测其长度。资源服务应该对其发布的任何Id进行说明。

2.3 Client Authorization(客户端授权)

如果客户端类型是机密,客户端和服务器会建立适合的安全方法达到服务器的安全要求。权限服务器可能接受客户端任何符合安全要求的数据。

机密类型的客户端可能被权限服务器授予一系列的凭证,用于授权(如用户名密码、共有/私有的key值对)。

权限服务器可能和公共类型的客户端建立授权方法,但是权限服务器不能依赖公共方法确定客户端的身份。

在每个请求中只能调用一个方法。

2.3.1 Client Password (客户端密码)

使用密码的客户端可能通过基本的Http授权方式向权限服务器请求授权RFC2617。客户端Id使用”application/x-www-form-urlencoded”编码并使用username作为Key,密码使用同样地编码方式并使用password作为Key。权限服务器必须支持基本Http授权的模式。

举例: Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3

可选的,权限服务器可以支持使用Request_Body中包含参数的方式:

  • client_id

必须。客户端Id在注册过程中发布给客户端(2.2节)。

  • client_secret 必须。client secret。当其为空时客户端可以忽略这个参数。

一般不推荐使用Rquest_Body的方式,而且应该仅限在客户端无法使用基本Http授权机制(和其它的授权机制)时。参数只能包含在RequestBody中,不能通过URI传递。

举例,使用RequestBody刷新AccessToken的请求:

 POST /token HTTP/1.1
 Host: server.example.com
 Content-Type: application/x-www-form-urlencoded

 grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
 &client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw

在使用密码进行授权时,权限服务器必须要求使用TLS(在6.1节中描述)。

因为这种机制引入了密码,权限服务器必须保护它以免任何终端利用暴力攻击的方式。

2.3.2 其它授权方法

权限服务器可选择任何满足安全要求的Http授权机制。当使用其它授权方法时,权限服务器必须定义客户端Id和授权机制直接的映射。

2.3.3 未注册用户

该协议不排除未注册客户端的使用,但是相关讨论超出了协议范围,并且需要额外的安全分析和重新审视对互操作性的冲突。

OAuth2 Specification Introduction

OAuth 2.0


1.1 Role

  • Resource Owner:资源的拥有者,当资源拥有者指人的时候一般是终端用户。
  • Resource Server:资源不熟的服务器。负责响应合法Access_Token的资源请求。
  • Client:请求资源的客户端,可以使其它应用的服务器、桌面应用、其它设备等。
  • Authorization Server:授权服务器。在【资源拥有者】授权后颁发给Client合法的Access_Token,并保存授权信息。

1.2 Protocol Flow

+--------+                               +---------------+
 |        |--(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

  1. Client直接或者间接向Resource Owner索取资源的授权。
  2. Resource Owner返回授权信息给Client(grant code)。
  3. Client向Authorization Server发送包含授权信息的请求。
  4. Authorization Server颁发Access_Token给Client。
  5. Client使用Access_Token向Resource Server请求感兴趣的资源。
  6. Resource Server验证Access_Token的有效性(向Authorization Server)后,响应Client请求。

1.3 Authorization Grant

认证授权是一张代表了资源拥有者授权的证书,Client用它获取Access_Token。OAuth2提供了四种授权类型:authorization code, implicit, resource owner password credentials(UserName, Password),client credential——第四种提供客户端的可扩展性。

1.3.1 Authorization Code

通过介于Client和Resource Owner之间的Authorization Server获取授权码。与直接向Resource Owner索取授权不同,Client把Resource Owner导向授权服务器,在获取到授权后该服务器将Resource Owner和授权码导向Client。

在把Resource Owner和授权码导向Client之前,Authorization Server对其鉴权并获得授权。由于Resource Owner只需要和Authorization Server打交道,Resource Owner的证书不需要和Client共享的。

授权码的机制提供了几个安全方面重要的好处,比如鉴定Client、直接把Access_Token传递给Client,而不需要经过Resource Owner——那将存在暴露给第三方的潜在风险。

1.3.2 Implicit(简化)

Implicit流程是Authorization Code的简化版本,主要用于浏览器中脚本实现。在Implicit流程中不是颁发授权码(Authorization Code)而是直接传递Access_Token给Client。这个授权过程是暗含的,这其中没有中间证书的发布(如Authorization Code)。

在传递Access_Token给Client的过程中,Authorization Server是不对Client鉴定的。有些情况下,可能通过Redirect Url鉴定Client,但是在发布过程中Access_Token可能会被Resource Owner和任何有权获得Client User-Agent的设备截获。

暗含授权机制提升了一些客户端(如浏览器内App)的响应性和效率,因为它降低了获得Access_Token过程中的交互旅程。然而,必须权衡该便利性带来的安全方面的损失,特别是在Authorization Code方式可选的时候,这部分将在10.310.6节讲述。

1.3.3 Resource Owner Password Credentials

Resource Owner的密码证书(如用户名+密码)可以作为直接获得Access_Token的授权方式。这种授权方式应该只在Resource Owner和Client存在充分信任的情况下使用,而且是其它授权机制无法使用时(比如Client是客户设备操作系统的一部分或者高优先级的程序)。

虽然这种认证方式要求Client能够直接访问Resource Owner的密码证书,但是还是要求在单独的请求中传递Resource Owner的证书来换取密码。该机制应避免在Client中记录Resource Owner的密码,可以通过使用长期的Access_Token或者Refresh_Token方式代替。

1.3.4 Client Credentials

当被请求资源是Client自己控制的或者被请求资源是预先与Authorization Server商定好的场景下,可以采用客户端(Client)认证。Client Credential被用作鉴权方案,通常是Client就是Resource Owner自身或者是被请求资源的授权已经预先在Authorization Server设定好的。

1.4 Access Token

Access Token是用来获取被保护资源的凭证。一个Access Token是一段代表了向client授权的字符串。该字符串对Client通常非透明的。它规定了授权的区间和范围,由Resource Owner授权,由Authorization Server和Resource Server执行。

Access Token可能是用于检索权限信息的Id,也可能是符合某种校验规格的包含权限信息的数据(比如包含数据和签名)。客户端(Client)在使用Access Token时可能还要引入额外的鉴权机制——这超出了该规格的讨论范围。

Access Token提供了一个授权的抽象层,使用可被Resource Server理解的单一token替代了其它不同的验证机制。在这个抽象中发布证书的动作比授权证书的动作更严格,同时免去了Resource Server要了解一大堆授权方法的痛苦。

基于Resource Server对安全性的要求,Access tokens可以存在不同的格式、构造和可用方法。Access Token的属性和方法超出了本规格的范围,在一些同伴规格比如[RFC6750]中有其相关的定义。

1.5 Refresh Token

Refresh Token是一种用于获取Access Token的凭证。Refresh Token由Authorization Server发布,用于获取新的Access Token(当原有变为非法或失效后),或者用于获得具备同样或者更窄范围的额外Access Token(一个生命周期更短,或者范围比Resource Owner授权的更窄的Access Token)。是否发布Refersh Token是Authorization Server自主决定的。Refresh Token的发布是包含在Access Token的发布中的。

Refresh Token是代表了Resource Owner授权的字符串,通常对Client是非透明的。这个字符串代表了获取授权信息的Id。与Access Token不同 Refresh Token只用于和Authorization Server交互,不会用于Resource Server。

  +--------+                                           +---------------+
  |        |--(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

图标2中展示的流程:

  1. 客户端向权限服务器发送授权信息和鉴定请求,请求一个Access Token。
  2. 权限服务器鉴定客户端并验证授权信息的合法性,如果合法发布一个Access Token和一个Refresh Token。
  3. 客户端提交对受保护资源的请求和Access Token。
  4. 资源服务器鉴定Access Token合法性,如合法响应请求。
  5. 步骤(3)和步骤(4)不断进行,直到Access Token失效。如果客户端发觉Access Token失效它会跳转到步骤(7),否则继续(3)。
  6. 因为Access Token已经失效,资源服务器返回token失效错误。
  7. 客户端传递鉴定请求和Refresh Token给权限服务器,获取新的Access Token。客户端的授权需求基于客户端类型和权限服务器的策略。
  8. 权限服务器鉴权Client并验证Refresh Token,如果合法,发布新的Access Token(有可能包括新的Refresh Token)。

步骤3,4,5,6超出了本规格范围。

1.6 TLS Version

TLS(Transport Layer Security)。无论该协议选择哪个TLS,随着广泛部署和安全弱点的暴露,都有会心的TLS出现。到目前为止TLS 1.2是最新的版本,但是它还存在较多部署限制并且可能还不适合实现。TLS 1.0RFC2246是目前最广泛部署的版本,并且提供了良好的协同性。

不同的实现可能还选择了额外的TLS机制满足他们的安全需要。

1.7 HTTP Redirections

在协议中扩展使用了Http重定向,客户端或者权限服务器使用这种方式彼此传递Resource Owner的user-agent。在当前协议中使用了Http的302状态码的方式,其它经由user-agent的方式也是被允许的并且可以视为一种具体实现。

1.8 Interoperability(互操作性)

OAuth 2.0提供了一个丰富的框架和良好定义的安全特性。然而,作为一个包含众多可选组件的丰富且高可扩展的框架,就自身而言,这份协议倾向于产生一个广泛的不可互操作的实现。

除此以外,协议中有少量的必要组件是部分实现或未实现(如客户端注册、权限服务器扩展性、终端发现)。缺失了这些组件,客户端只能人工并且针对权限服务器和资源服务器配置才能实现互操作性。

协议的定义存在一个明确的期待——将来的工作会定义规范的资料和必要的扩展,以实现全面的网络层互操作性。

1.9 Notational Conventions(标记约定)

关键字”MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL”的示意在RFC2119中定义.

本协议使用Augmented Backus-Naur Form (ABNF)RFC5234标记。此外, 从”Uniform Resource Identifier (URI): Generic Syntax“ RFC3986引入了URI-reference的规定。

某些安全相关的短语采用RFC4949中的场景理解.这些短语包括但不限于:”attack”, “authentication”, “authorization”, “certificate”,“confidentiality”, “credential”, “encryption”, “identity”, “sign”,“signature”, “trust”, “validate”, and “verify”.

除非特殊说明,左右协议的参数名和值都是大小写敏感的。

Create the First Post

安装

前置依赖

  1. git
  2. Ruby 1.9.3及以上版本,可以通过rbenv或RVM搞定。
  3. 安装ExecJS中支持的任意JavaScript运行时环境。

设置Octopress

源文件下载

git clone git://github.com/imathis/octopress.git octopress
cd octopress

解决依赖关系

gem install bundler
rbenv rehash    # If you use rbenv, rehash to be able to run the bundle command
bundle install

安装默认主题的Octopress

rake install

设置部署

这里选择的Github Pages,从略。

创建Blog

使用命令创建一篇Blog,blog文件位于source/_posts/目录下:

rake new_post[your blog name]

使用任意编辑器编辑blog,完成保存执行命令:

rake generate

本地测试

使用命令启动本地服务器,端口4000.

rake preview

部署

rake deploy