OAuth2.0介紹
- OAuth2.0簡介
- 四種許可類型
2.1. 授權碼許可(Authorization Code)
2.2. 隱式許可(Implicit)
2.3. 資源擁有者密碼憑據許可(Resource Owner Password Credentials)
2.4. 客戶端憑據許可(Client Credentials)
1、OAuth2.0簡介
OAuth2官網是這么描述的:
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.md
白話
OAuth2 是一個開放授權協議標准,它允許用戶(資源擁有者)讓第三方應用訪問該用戶在某服務的特定私有資源(資源服務器)但是不提供賬號密碼信息給第三方應用。
角色
1、Resource Owner:資源擁有者(能夠許可對受保護資源的訪問權限的實體。當資源擁有者是個人時,它被稱為最終用戶。)
2、Resource Server:資源服務器(托管受保護資源的服務器,能夠接收和響應使用訪問令牌對受保護資源的請求。)
3、Client:第三方應用客戶端(使用資源擁有者的授權代表資源擁有者發起對受保護資源的請求的應用程序)
4、Authorization Server :授權服務器(在成功驗證資源擁有者且獲得授權后頒發訪問令牌給客戶端的服務器。)
協議流程
+--------+ +---------------+
| |--(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 ---| |
+--------+ +---------------+
抽象的OAuth2.0流程描述
(A)客戶端從資源擁有者處請求授權。授權請求可以直接向資源擁有者發起(如圖所示),或者更可取的是通過授權服務器作為中介間接發起。
(B)客戶端收到授權許可,這是一個代表資源擁有者的授權的憑據,使用本規范中定義的四種許可類型之一或者使用擴展許可類型表示。授權許可類型取決於客戶端請求授權所使用的方法以及授權服務器支持的類型。
(C)客戶端與授權服務器進行身份認證並出示授權許可以請求訪問令牌。
(D)授權服務器驗證客戶端身份並驗證授權許可,若有效則頒發訪問令牌。
(E)客戶端從資源服務器請求受保護資源並出示訪問令牌進行身份驗證。
(F)資源服務器驗證訪問令牌,若有效則處理該請求。
2、四種許可類型
1、Authorization Code:授權碼許可;
2、Implicit:隱式許可;
3、Resource Owner Password Credentials:資源擁有者密碼憑據許可;
4、Client Credentials :客戶端憑據許可。
2.1、授權碼許可(Authorization Code)
授權碼模式是最常見的一種授權模式,最為安全和完善。
適用范圍
需要得到長期授權,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相匹配。如果通過,授權服務器響應返回訪問令牌與可選的刷新令牌。
過程詳解
授權請求(A)
參數 | 是否必須 | 含義 |
---|---|---|
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
授權響應(C)
參數 | 是否必須 | 含義 |
---|---|---|
code | 必需 | 授權服務器生成的授權碼。授權碼必須在頒發后很快過期以減小泄露風險。 推薦的最長的授權碼生命周期是10分鍾。客戶端不能使用授權碼超過一次。 如果一個授權碼被使用一次以上,授權服務器必須拒絕該請求並應該撤銷(如可能) 先前發出的基於該授權碼的所有令牌。 授權碼與客戶端標識和重定向URI綁定。授權服務器生成的授權碼。 授權碼必須在頒發后很快過期以減小泄露風險。 |
state | 必需 | 客戶端提供的state參數原樣返回。 |
示例:
HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
訪問令牌請求(D)
參數 | 是否必須 | 含義 |
---|---|---|
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.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.3、資源擁有者密碼憑據許可(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.4、客戶端憑據許可(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 | 可選 | 表示授權范圍。 |
示例:
客戶端身份驗證兩種方式
1、Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3。
2、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"
}