The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.
官方文档:https://tools.ietf.org/html/rfc6749
中文文档:https://github.com/jeansfish/RFC6749.zh-cn/blob/master/index.mdhtml
白话
OAuth2 是一个开放受权协议标准,它容许用户(资源拥有者)让第三方应用访问该用户在某服务的特定私有资源(资源服务器)可是不提供帐号密码信息给第三方应用。git
一、Resource Owner:资源拥有者(可以许可对受保护资源的访问权限的实体。当资源拥有者是我的时,它被称为最终用户。)
二、Resource Server:资源服务器(托管受保护资源的服务器,可以接收和响应使用访问令牌对受保护资源的请求。)
三、Client:第三方应用客户端(使用资源拥有者的受权表明资源拥有者发起对受保护资源的请求的应用程序)
四、Authorization Server :受权服务器(在成功验证资源拥有者且得到受权后颁发访问令牌给客户端的服务器。)github
+--------+ +---------------+ | |--(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 ---| | +--------+ +---------------+
(A)客户端从资源拥有者处请求受权。受权请求能够直接向资源拥有者发起(如图所示),或者更可取的是经过受权服务器做为中介间接发起。
(B)客户端收到受权许可,这是一个表明资源拥有者的受权的凭据,使用本规范中定义的四种许可类型之一或者使用扩展许可类型表示。受权许可类型取决于客户端请求受权所使用的方法以及受权服务器支持的类型。
(C)客户端与受权服务器进行身份认证并出示受权许能够请求访问令牌。
(D)受权服务器验证客户端身份并验证受权许可,如有效则颁发访问令牌。
(E)客户端从资源服务器请求受保护资源并出示访问令牌进行身份验证。
(F)资源服务器验证访问令牌,如有效则处理该请求。json
受权码模式是最多见的一种受权模式,最为安全和完善。
适用范围
须要获得长期受权,OAuth客户端是Web应用服务器,OAuth访问令牌不宜泄露给用户的环境。浏览器
Authorization Code具体的流程以下:安全
+----------+ | 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)客户端经过向受权端点引导资源拥有者的用户代理开始流程。客户端包括它的客户端标识、请求范围、本地状态和重定向URI,一旦访问被许可(或拒绝)受权服务器将传送用户代理回到该URI。
(B)受权服务器验证资源拥有者的身份(经过用户代理),并肯定资源拥有者是否授予或拒绝客户端的访问请求。
(C)假设资源拥有者许可访问,受权服务器使用以前(在请求时或客户端注册时)提供的重定向URI重定向用户代理回到客户端。重定向URI包括受权码和以前客户端提供的任何本地状态。
(D)客户端经过包含上一步中收到的受权码从受权服务器的令牌端点请求访问令牌。当发起请求时,客户端与受权服务器进行身份验证。客户端包含用于得到受权码的重定向URI来用于验证。
(E)受权服务器对客户端进行身份验证,验证受权代码,并确保接收的重定向URI与在步骤(C)中用于重定向(资源拥有者的用户代理)到客户端的URI相匹配。若是经过,受权服务器响应返回访问令牌与可选的刷新令牌。服务器
参数 | 是否必须 | 含义 |
---|---|---|
response_type | 必需 | 受权类型,值固定为“code”。 |
client_id | 必需 | 客户端标识。 |
redirect_uri | 可选 | 成功受权后的回调地址。 |
scope | 可选 | 表示受权范围。 |
state | 推荐 | client端的状态值。用于第三方应用防止CSRF攻击,成功受权后回调时会原样带回。 |
示例:微信
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
参数 | 是否必须 | 含义 |
---|---|---|
code | 必需 | 受权服务器生成的受权码。受权码必须在颁发后很快过时以减少泄露风险。 推荐的最长的受权码生命周期是10分钟。客户端不能使用受权码超过一次。 若是一个受权码被使用一次以上,受权服务器必须拒绝该请求并应该撤销(如可能) 先前发出的基于该受权码的全部令牌。 受权码与客户端标识和重定向URI绑定。受权服务器生成的受权码。 受权码必须在颁发后很快过时以减少泄露风险。 |
state | 必需 | 客户端提供的state参数原样返回。 |
示例:app
HTTP/1.1 302 Found Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
参数 | 是否必须 | 含义 |
---|---|---|
grant_type | 必需 | 受权类型,值固定为“authorization_code”。 |
code | 必需 | 从受权服务器收到的受权码。 |
redirect_uri | 必需 | 必须和受权请求中提供的redirect_uri相同。 |
client_id | 必需 | 必须和受权请求中提供的client_id相同。 |
示例:微信公众平台
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb##### 访问令牌响应(E)
参数说明 | 是否必须 | 描述 |
---|---|---|
access_token | 必需 | 受权令牌,Access_Token。 |
token_type | 必需 | 表示令牌类型,该值大小写不敏感,能够是bearer类型或mac类型。 |
expires_in | 推荐 | 该access token的有效期,单位为秒。若是省略,则受权服务器应该经过其余方式提供过时时间,或者记录默认值。 |
refresh_token | 可选 | 在受权续期时,获取新的Access_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":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }
参考 QQ OAuth2 API(Authorization Code)
### 2.二、隐式许可(Implicit)相比受权码许可,隐式许可少了第一步获取Authorization Code的过程,所以变得更为简单。但正由于如此也下降了安全性。受权服务器不能颁发刷新令牌。
适用范围
其适用于没有Server服务器来接受处理Authorization Code的第三方应用。
仅需临时访问的场景,用户会按期在API提供者那里进行登陆,OAuth客户端运行在浏览器中(Javascript、Flash等)浏览器绝对可信,由于该类型可能会将访问令牌泄露给恶意用户或应用程序。
Implicit具体的流程以下:
+----------+ | 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 | | | +---------+
(A)客户端经过向受权端点引导资源拥有者的用户代理开始流程。客户端包括它的客户端标识、请求范围、本地状态和重定向URI,一旦访问被许可(或拒绝)受权服务器将传送用户代理回到该URI。
(B)受权服务器验证资源拥有者的身份(经过用户代理),并肯定资源拥有者是否授予或拒绝客户端的访问请求。
(C)假设资源拥有者许可访问,受权服务器使用以前(在请求时或客户端注册时)提供的重定向URI重定向用户代理回到客户端。重定向URI在URI片断中包含访问令牌。
(D)用户代理顺着重定向指示向Web托管的客户端资源发起请求。用户代理在本地保留片断信息。
(E)Web托管的客户端资源返回一个网页(一般是带有嵌入式脚本的HTML文档),该网页可以访问包含用户代理保留的片断的完整重定向URI并提取包含在片断中的访问令牌(和其余参数)。
(F)用户代理在本地执行Web托管的客户端资源提供的提取访问令牌的脚本。
(G)用户代理传送访问令牌给客户端。
参数 | 是否必须 | 含义 |
---|---|---|
response_type | 必需 | 受权类型,值固定为“token”。 |
client_id | 必需 | 客户端标识。 |
redirect_uri | 可选 | 成功受权后的回调地址。 |
scope | 可选 | 表示受权范围。 |
state | 推荐 | client端的状态值。用于第三方应用防止CSRF攻击,成功受权后回调时会原样带回。 |
示例:
GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 Host: server.example.com
参数说明 | 是否必须 | 描述 |
---|---|---|
access_token | 必需 | 受权令牌,Access_Token。 |
token_type | 必需 | 表示令牌类型,该值大小写不敏感,能够是bearer类型或mac类型。 |
expires_in | 推荐 | 该access token的有效期,单位为秒。若是省略,则受权服务器应该经过其余方式提供过时时间,或者记录默认值。 |
scope | 可选 | 表示受权范围。 |
state | 可选 | client端的状态值。用于第三方应用防止CSRF攻击,成功受权后回调时会原样带回。 |
示例:
#后的信息不会回传到服务端example.com/cb中。
HTTP/1.1 302 Found Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=example&expires_in=3600### 2.三、资源拥有者密码凭据许可(Resource Owner Password Credentials)
资源拥有者向客户端提供本身的用户名和密码。客户端使用这些信息,向受权服务器请求受权。
适用范围
这种模式会直接将用户密码暴露给客户端,通常适用于Resource server高度信任第三方Client的状况下。
Resource Owner Password Credentials具体的流程以下:
+----------+ | Resource | | Owner | | | +----------+ v | Resource Owner (A) Password Credentials | v +---------+ +---------------+ | |>--(B)---- Resource Owner ------->| | | | Password Credentials | Authorization | | Client | | Server | | |<--(C)---- Access Token ---------<| | | | (w/ Optional Refresh Token) | | +---------+ +---------------+
(A)资源拥有者提供给客户端它的用户名和密码。
(B)经过包含从资源拥有者处接收到的凭据,客户端从受权服务器的令牌端点请求访问令牌。当发起请求时,客户端与受权服务器进行身份验证。
(C)受权服务器对客户端进行身份验证,验证资源拥有者的凭证,若是有效,颁发访问令牌。
参数 | 是否必须 | 含义 |
---|---|---|
grant_type | 必需 | 受权类型,值固定为“password”。 |
username | 必需 | 资源拥有者的用户名。 |
password | 必需 | 资源拥有者的密码。 |
scope | 可选 | 表示受权范围。 |
示例:
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=password&username=johndoe&password=A3ddj3w
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }### 2.四、客户端凭据许可(Client Credentials)
客户端(Client)请求受权服务器验证,经过验证就发access token,Client直接以已本身的名义去访问Resource server的一些受保护资源。
适用范围
以客户端自己而不是单个用户的身份来读取、修改资源服务器所开放的API。
Client Credentials具体的流程以下:
+---------+ +---------------+ | | | | | |>--(A)- Client Authentication --->| Authorization | | Client | | Server | | |<--(B)---- Access Token ---------<| | | | | | +---------+ +---------------+
(A)客户端与受权服务器进行身份验证并向令牌端点请求访问令牌。
(B)受权服务器对客户端进行身份验证,若是有效,颁发访问令牌。
参数 | 是否必须 | 含义 |
---|---|---|
grant_type | 必需 | 受权类型,值固定为“client_credentials”。 |
scope | 可选 | 表示受权范围。 |
示例:
客户端身份验证两种方式
一、Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3。
二、client_id(客户端标识),client_secret(客户端秘钥)。
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=client_credentials
参数介绍参见 Authorization Code中的访问令牌响应
刷新令牌不该该包含在内。
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "example_parameter":"example_value" }