OAuth--Open standard for Authorization

 

       OAUTH

1. 什么是OAuth ?

官网这样说...php

An open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications.web

  • OAuth 即 Open standard for Authorization
  • OAuth就是一个网络开放协议。为保证用户资源的安全受权提供了简易的标准
  • 在知乎上看到了一个比较直观的比喻,有助于初学者理解。知乎话题连接

2. OAuth 历史版本

  • 2007-12 OAuth 1.0发布并迅速成为工业标准。
  • 2008-06 OAuth 1.0 Revision A发布,这是个稍做修改的修订版本,主要修正一个安全方面的漏洞。
  • 2010-04,OAuth 1.0 协议发布为 RFC 5849
  • 2011-05 OAuth 2.0 草案发布
  • 2012-10 OAuth 2.0 协议发布为 RFC 6749

3. OAuth 1.0

OAuth 1.0 协议过于复杂,易用性差,因此并无获得普及,下文中给出了受权的流程图,能够简单了解了解,如今不多有用的了。浏览器

OAuth Authentication Flow

OAuth Authentication Flow安全

关于OAuth 1.0, 想了解的能够看看这些:服务器

4. OAuth 2.0

OAuth 2.0是目前的最新版本,OAuth 2.0不兼容OAuth 1.0。这篇文章主要讲讲OAuth 2.0,并以此展开。网络

先来讲一个场景:好比你第一次打开简书官网,想要注册一个帐号。你会看到简书容许你经过新浪微博帐号登录。当你点击以后,须要你登录微博。以后会出现“是否赞成简书获取你的我的信息”等等,若是你选择受权,以后会跳转回简书。你会发现你在简书的用户名就是你微博的用户名。而后,你会发出一条新的微博好比“我加入了简书,一个基于内容分享的社区!”(这只是举个例子,不知道简书有没有这样作)。app

好了,这回开始进入正题ide

4.1 角色(roles)

OAuth 2.0 定义了四个角色网站

  • 资源拥有者(Resource Owner)
    资源拥有者其实就是用户(user),用户将会受权一个第三方应用能够获取他们的帐户资源。固然第三方应用程序对于用户帐户的操做是有限制的(好比,read access, read and write access)!这个限制就是用户受权时给予的权限范围(scope)
    上面场景中,微博帐户就是资源拥有者。read access就好比读取微博用户名,write access就好比以你的名义发了一个微博。spa

  • 客户端(Client)
    客户端就是前面说的第三方应用程序,他们想要获取用户的帐户资源,但在这么作以前必须通过受权
    上面场景中,简书就是客户端

  • 资源服务器(Resource Server)
    资源服务器存放用户帐户以及帐户信息和资源
    上面场景中,新浪微博就是资源服务器,同时也是受权服务器

  • 受权服务器(Authorization Server)
    受权服务器验证用户身份,并为第三方应用程序颁发受权令牌(access token)

资源服务器与受权服务器能够是同一台服务器,这里分开主要是便于解释清楚OAuth协议。从程序开发者的角度,这两个都是service's API会执行的事情。

在了解完OAuth中的四个角色以后,咱们看看这四个角色之间是如何互动的。下面是基本运行流程。

Abstract Protocol Flow

Abstract Protocol Flow

  1. 应用程序向用户请求给予受权,以便获取服务器资源
  2. 若是用户赞成受权,应用程序将得到相应受权
  3. 应用程序向受权服务器提供本身的身份证实(app key和app secret)和已被受权的证实(authorization grant),并请求访问令牌(access token)
  4. 若是应用程序的身份被核实,而且受权是有效地,那么受权服务器将会发放访问令牌给应用程序。此时,受权完成
  5. 应用程序向资源服务器出示访问令牌,并请求资源
  6. 若是访问令牌是有效的(好比:是否伪造,是否越权,是否过时),资源服务器将会为应用程序提供资源

4.2 应用程序注册(Application Registration)

对于一个应用程序来讲,若是它想要使用OAuth,那么首先它要在服务提供商那里注册。通常出如今网站的“developer”或者“API”部分。

应用程序要提供:

  • 应用程序名称(Application Name)
  • 应用程序网站(Application Website)
  • 回调URL(Redirect URI or Callback URL)

在用户赞成受权(或者拒绝)以后,服务提供商会将用户从新导向这个Callback URL,这个Callback URL要来负责处理受权码或者访问令牌。

应用程序注册完成以后,服务提供商会颁发给应用程序一个“客户端认证信息(client credentials)”。Client Credential包括:

  • Client Identifier(client ID/API key/consumer key)
    • 提供给服务提供商,用于识别(identify)应用程序
    • 用于构建提供给用户请求受权的URLs
  • Client Secret(secret key/API secret/consumer secret)
    • 提供给服务提供商,用于验证(authenticate)应用程序
    • 只有应用程序和服务提供商二者可知

4.3 受权许可类型(Authorization grant types)

OAuth 2.0 定义了四种受权模式:

  • 受权码模式(Authorization Code)
    used with server-side Applications
  • 隐式受权模式(Implicit)
    used with Mobile Apps or Web Applications (applications that run on the user's device)
  • 资源拥有者密码凭证模式(Resource Owner Password Credentials)
    used with trusted Applications, such as those owned by the service itself
  • 客户端模式(Client Credentials)
    used with Applications API access

4.4 受权码模式(Authorization Code)

  • 受权码模式是最多见的一种受权模式,最为安全和完善。
  • 对于服务器端应用程序(server-side application)来讲,能够保证Client Secret的安全性。应用程序必须可以和用户代理(user agent)进行交互,获取API受权码。

Authorization Code Flow

Authorization Code Flow

第一步:客户端把用户代理定向到受权终端(Authorizaiton Endpoint)

https://www.example.com/v1/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read
  • www.example.com/v1/oauth/authorize: API受权的终端(Authorization Endpoint)
  • client_id: 应用程序的client ID,用于API识别应用程序
  • redirect_uri:得到受权码以后,服务提供商重定向用户代理(好比浏览器)的地址
  • response_type:代表受权类型,默认值是code,即受权码模式(Authorization Code Grant)
  • scope: 即应用程序能够得到的受权级别(access level),默认值为read
  • state: 表示客户端的当前状态,能够指定任意值,认证服务器会原封不动地返回这个值,用于抵制CSRF攻击。

第二步:用户受权应用程序

用户点击上述URI以后,用户首先要登录,证实其身份。而后选择赞成受权应用程序能够访问他们的帐户或者拒绝。

是否容许简书访问你的微博帐户

是否容许简书访问你的微博帐户

第三步:应用程序获取受权码

若是用户赞成受权,服务提供商会将用户代理重定向到第一步中的redirect_uri,而且会包含受权码

https://www.jianshu.com/callback?code=AUTHORIZATION_CODE

第四步:应用程序请求受权令牌

应用程序向API token终端发送刚刚得到的受权码,以及认证信息。

https://www.example.com/v1/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL

URI中包括:

  • www.example.com/v1/oauth/token: API token的终端
  • client_id:即app key/consumer key,用于验证应用程序
  • client_secret: 即app secret/consumer secret,用于验证应用程序
  • grant_type:刚刚得到的受权码
  • redirect_uri: 重定向URI,与第一步一致

第五步:应用程序得到受权令牌

若是上一步验证有效,API将返回一个HTTP回复。

{"access_token":"ACCESS_TOKEN","token_type":"bearer","expires_in":2592000,"refresh_token":"REFRESH_TOKEN","scope":"read"}

HTTP回复中包含:

  • access_token:访问令牌
  • token_type:令牌类型,bearer类型或mac类型。详细
  • expires_in:过时时间,单位为秒。
  • refresh_token:更新令牌,用来获取下一次的访问令牌,可选项。
  • scope:权限范围,若是与客户端申请的范围一致,此项可省略。

4.5 隐式受权模式(Implicit)

  • 隐式受权模式主要用于客户端应用程序(client-side application),好比手机应用、桌面客户端应用程序和运行于浏览器上的web应用程序。
  • 由于没有server端,client secret的保密性不能获得保证。受权令牌给予用户代理(好比,浏览器),再由用户代理交给应用程序。因此用户设备上的其余应用程序一样能够获得受权令牌。
  • 隐式受权模式中,应用程序不须要认证。
  • 隐式受权模式不支持refresh token。

Implicit Flow

Implicit Flow

第一步:客户端把用户代理定向到受权终端(Authorizaiton Endpoint)

  • 受权终端是https://www.example.com/authorize
  • 与受权码连接相似,只不过response_type=token而不是code
https://www.example.com/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read

第二步:用户受权应用程序

用户点击上述URI以后,用户首先要登录,证实其身份。而后选择赞成受权应用程序可访问他们的帐户或者拒绝

是否容许简书访问你的微博帐户

是否容许简书访问你的微博帐户

第三步:用户代理收到受权令牌

假设用户赞成受权,受权服务器重定向用户代理到第一步提到的redirect_uri。并在URI fragment中包含受权令牌(但不能查看)。

https://www.example.com/callback#token=ACCESS_TOKEN

第四步:用户代理向资源服务器发出请求

用户代理依照重定向的指令,向资源服务器发出请求,但并不包含上一步中获得的受权令牌(#后面的部分)。用户代理将完整的重定向URI保存在本地。

第五步:资源服务器返回一个网页

资源服务器会返回一个网页(一般是一个HTML文件内嵌一段脚本)。这段内嵌的脚本(script)能够访问第三步中用户代理保存在本地的完整的重定向URI,并从中提取受权令牌。

第六步:用户代理提取受权令牌

用户代理执行上面提到的脚本,提取出受权令牌。而后将受权令牌传递给应用程序。

4.6 资源拥有者密码凭证模式(Resource Owner Password Credentials)

  • 在资源拥有者密码凭证模式中,用户直接向应用程序提供其认证信息(即用户名和密码)。应用程序依此向受权服务器获取受权令牌。
  • 这种模式适用于用户对应用程序高度信任的状况。好比是用户操做系统的一部分。
  • 认证服务器只有在其余受权模式没法执行的状况下,才能考虑使用这种模式。

Password Credentials Flow

Password Credentials Flow

第一步:用户传递认证信息

用户将用户名和密码交给应用程序。

第二步:应用程序请求受权令牌

  • 应用程序获得用户认证信息后,向受权服务器请求受权令牌。
  • 请求受权令牌终端https://www.example.com/token
  • response_type=password,前面提到的两种分别是codetoken
https://www.example.com/token?grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID

第三步:受权服务器返回受权令牌

若是用户的认证信息获得验证,受权服务器将向应用程序返回受权令牌。

4.7 客户端模式(Client Credentials)

  • 客户端模式应用于应用程序想要以本身的名义与受权服务器以及资源服务器进行互动。
  • 好比应用程序想要修改自身注册信息或者redirect URI。又或者想要获取资源服务器中不与具体用户相关的信息。好比一个应用程序想要获取新浪微博中含有#happy的微博。
  • 严格意义上说,客户端模式并非OAuth协议要解决的问题,由于并未涉及受权。

Client Credentials Flow

Client Credentials Flow

第一步:应用程序请求受权令牌

  • 应用程序向受权服务器提供自身认证信息(client ID和client secret),并请求受权令牌。
  • 请求受权令牌终端https://www.example.com/token
  • response_type=client_credentials,前面提到的两种分别是codetokenpassword
https://www.example.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET

第二步:受权服务器返回受权令牌

受权服务器验证认证信息,向应用程序返回受权令牌。

4.7 更新令牌(Refresh Token)

  • 若是受权令牌过时,在进行API请求时会报错Invalid Token Error
  • 若是在获取受权令牌时,同时得到了refresh token,那么咱们能够向受权服务器申请更新令牌。
  • grant_type = refresh_token
  • scope:表示申请的受权范围,不能够超出上一次申请的范围,若是省略该参数,则表示与上一次一致。
    https://www.example.com/v1/oauth/token?grant_type=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&refresh_token=REFRESH_TOKEN

                              原文:http://www.jianshu.com/p/b06944c92228

相关文章
相关标签/搜索