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" }