相關文件
OAuth 2.0 已標準化為 RFC 6749。如需詳細文件,請前往 https://oauth.net/2。HTTP 基本驗證定義於 RFC 2617 的第 2 節。
總覽
通常,如要讓第三方應用程式存取受限資源 (例如資料方案和錢包詳細資料),使用者 (資源擁有者) 必須與第三方共用憑證。這會造成多項問題和限制,例如憑證儲存、密碼驗證、廣泛存取使用者資源,以及密碼外洩等。OAuth 2.0 導入授權層,解決了這些問題,進而保護使用者資源並限制存取權。
GTAF 會取得存取權杖,而非使用者的憑證,藉此存取受保護的資源,例如資料方案詳細資料。存取權杖會以 GTAF 憑證的名義核發給 GTAF。接著,GTAF 會使用存取權權杖,存取 DPA 託管的資料方案詳細資料。
下圖提供資訊的概略流程:
圖 1. 抽象 OAuth 流程。
存取權杖
存取權杖是 GTAF 用來從電信業者的 DPA 存取資料方案詳細資料的憑證。存取權杖是一組字串,代表核發給 GTAF 的授權。字串通常對 GTAF 不透明。權杖代表使用者授予電信業者的特定存取範圍和時間長度,並由 DPA 和電信業者的 OAuth 伺服器強制執行。
存取權杖提供抽象層,以 DPA 可解讀的單一權杖,取代不同的授權建構體 (例如使用者名稱和密碼)。這種抽象化機制可發行比授權授予更嚴格的存取權杖,並讓 DPA 無需瞭解各種驗證方法。
存取權杖的格式、結構和使用方法 (例如密碼編譯屬性) 可能因電信業者的安全規定而異。GTAF 僅支援 [RFC6750] 中定義的不記名型存取權杖。
用戶端驗證
GTAF 可做為「機密用戶端」,確保密碼安全無虞。目前 GTAF 僅支援 HTTP 基本驗證,可透過 DPA 進行驗證。用戶端 ID 會使用「application/x-www-form-urlencoded」編碼演算法編碼,編碼值會做為使用者名稱;密碼會使用相同演算法編碼,並做為密碼。
機密用戶端 (例如 GTAF) 會取得用戶端憑證,並在向權杖端點提出要求時,透過電信業者的 OAuth 伺服器進行驗證。用戶端驗證的用途:\
- 停用用戶端或變更憑證,從遭入侵的用戶端復原,防止攻擊者濫用遭竊的重新整理權杖。變更一組用戶端憑證的速度,遠比撤銷整組重新整理權杖快。
- 實施驗證管理最佳做法,定期輪替憑證。
GTAF 會在傳送要求至權杖端點時,使用「client_id」要求參數識別自身。
其中,輪替用戶端憑證的功能尤其重要。OAuth 伺服器必須能在輪替期間支援兩組憑證,且必須能夠停用憑證。一般憑證輪替程序如下:
- 電信業者會在 OAuth 伺服器上建立新憑證,並以安全的方式將憑證提供給技術帳戶管理員。
- Google 會測試新憑證,並變更 GTAF 設定以使用新憑證。
- Google 會通知電信業者,舊憑證可能會停用。
- 電信業者停用憑證並通知 Google
- Google 會驗證舊憑證是否已失效
OAuth 伺服器必須支援上述輪替程序。
權杖端點
GTAF 會使用權杖端點,出示授權授予或更新權杖來取得存取權杖。除了隱含授權類型 (因為系統會直接核發存取權杖),所有授權許可都會使用權杖端點。
設定權杖端點時,請注意下列事項:
- 權杖端點的位置應在服務文件中提供。
- 端點 URI 可能包含「application/x-www-form-urlencoded」格式的查詢元件,新增其他查詢參數時必須保留此元件。端點 URI 不得包含片段元件。
- 由於對權杖端點的要求會導致傳輸純文字憑證 (在 HTTP 要求和回應中),因此電信業者的 OAuth 伺服器必須使用 TLS,才能將要求傳送至權杖端點。
- GTAF 在要求存取權杖時,會使用 HTTP「POST」方法。
- 如果傳送的參數沒有值,必須視為從要求中省略。 OAuth 伺服器必須忽略無法辨識的要求參數。要求和回應參數不得重複出現。
- GTAF 僅支援承載權杖類型的存取權杖。
存取權杖範圍
用戶端可透過授權和權杖端點,使用「scope」要求參數指定存取要求範圍。授權伺服器會使用「scope」回應參數,通知用戶端核發的存取權杖範圍。
範圍參數的值會以空格分隔的字串清單表示,且須區分大小寫。這些字串是由授權伺服器定義。如果值包含多個以半形空格分隔的字串,這些字串的順序並不重要,每個字串都會為要求的範圍新增額外的存取範圍。
scope = scope-token *( SP scope-token )
scope-token = 1*( %x21 / %x23-5B / %x5D-7E )
GTAF 不需要實作範圍,但支援這項功能。詳情請參閱 RFC 6749 的第 3.3 節。
核發存取權杖
如果 GTAF 傳送的存取權杖要求有效且已獲得授權,OAuth 伺服器就會核發存取權杖和選用的更新權杖。如果要求無法通過用戶端驗證或無效,OAuth 伺服器會傳回錯誤回應,如下一節所述。
成功回應
當 GTAF 傳送要求時,OAuth 伺服器會核發存取權杖和選用的重新整理權杖,並在 HTTP 回應的實體主體中加入下列參數,建構回應 (狀態碼為 200 (OK)):\
- access_token:必要。OAuth 伺服器核發的存取權杖。 GTAF 預期權杖端點會傳回不記名權杖。
- expires_in:必要。存取權杖的生命週期 (以秒為單位)。舉例來說,值為「3600」表示存取權杖會在產生回應後一小時到期。如果省略,OAuth 伺服器應透過其他方式提供到期時間,或記錄預設值。
- token_type:必要。發出的權杖類型。如要進一步瞭解不同類型的權杖,請參閱 RFC 6749 的 第 7.1 節。這個值不區分大小寫。在撰寫本文時,GTAF 僅支援不記名權杖。
- refresh_token:選用。更新權杖,可用於透過相同授權授予取得新的存取權杖。
- 範圍:選用。如果實作範圍與 GTAF 要求範圍相同,則為選用;否則為必要。
這些參數會使用「application/json」納入 HTTP 回應的實體主體。在最高結構層級新增每個參數,即可將參數序列化為 JavaScript 物件表示法 (JSON) 結構。參數名稱和字串值會以 JSON 字串的形式納入。數值會以 JSON 數字的形式納入。參數順序不重要,而且可能會有所不同。
授權伺服器必須在任何包含符記、憑證或其他私密資訊的回應中,加入值為「no-store」的 HTTP「Cache-Control」回應標頭欄位,以及值為「no-cache」的「Pragma」回應標頭欄位。
例如:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"Bearer",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}
以下是需要考量的幾項重點:
- GTAF 會忽略回應中無法辨識的值名稱。
- 從 OAuth 伺服器收到的權杖和其他值大小未定義。
- GTAF 應避免對值大小做出假設。OAuth 伺服器應記錄發出的所有值的大小。
錯誤回應
如果授權要求因任何原因而失敗,例如缺少、無效或不相符的重新導向 URI,或是缺少或無效的用戶端 ID,OAuth 伺服器應傳回 HTTP 400 (不正確的要求) 狀態碼 (除非另有規定),並至少包含「錯誤回應和代碼」一節中列出的其中一個參數。
GTAF 中的授權許可
授權許可是一種憑證,代表 GTAF 用來取得存取權權杖的授權,可存取受保護的資源,例如資料餘額資訊。
GTAF 使用 client_credentials 授權類型。在 client_credentials 授權類型中,GTAF 會使用 HTTP POST 要求和 HTTP 基本驗證要求權杖。所有要求都會透過 TLS 傳送 (即HTTPS),且 GTAF 無法與沒有有效 TLS 憑證的 OAuth 伺服器整合。GTAF 可傳遞可設定的權杖範圍,如果未設定範圍,則會傳遞空白範圍。
GTAF 預期會連同「expires_in」值 (存留時間) 一併傳回存取權杖。expires_in 值應至少為 900 秒,且不應超過幾小時。要求新權杖時,現有權杖不得提早過期。
如要進一步瞭解各種授權類型,請參閱 RFC 6749 的第 1.3 節。
要求和回應範例
假設 GTAF 的 OAuth 伺服器設定如下:
URL: https://www.example.com/gettoken/
Client ID: gtaf
Client secret: password
Scope: dpa
注意:實際 DPA 的用戶端密鑰必須比範例中顯示的密鑰安全許多。
如要產生授權字串,請將用戶端 ID、':' 和密碼串連在一起,然後進行 Base64 編碼。這可以在指令列介面中複製,如下所示:
$ echo -n gtaf:password | base64
Z3RhZjpwYXNzd29yZA==
接著,GTAF 會使用這些憑證、client_credentials 授權類型和設定的範圍,向 OAuth 伺服器發出 HTTPS POST 要求。以這個範例來說,GTAF 的要求與下列項目產生的要求類似:
$ curl -H 'Authorization: Basic Z3RhZjpwYXNzd29yZA==' -X POST \
-d 'grant_type=client_credentials&scope=dpa' 'https://www.example.com/gettoken/'
GTAF 使用的標頭與 curl 傳送的標頭不符,但授權標頭會相同。
GTAF 預期會收到以下格式的回覆:
{
"access_token":"<token>",
"token_type": "Bearer",
"expires_in":<expiration time>
}
以下是有效回應的範例:
{
"access_token":"YXRudWhhZXVoLGFodWFoaGF1aG9zaHVvYWV1Cg",
"token_type": "Bearer",
"expires_in":3600
}
注意:回應必須是有效的 JSON。
錯誤回應和代碼
如果 GTAF 的授權要求因「錯誤回應」一節所述的任何原因而失敗,OAuth 伺服器必須回應 HTTP 400 (不正確的要求) 狀態碼 (除非另有規定),並在回應中加入下列其中一個參數:
例如:\
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"error":"invalid_request"
}
GTAF 預期 OAuth 伺服器會支援下列錯誤回應:
錯誤代碼 | 回應 | 原因 |
HTTP 400 | invalid_request | 要求缺少必要參數、包含不支援的參數值 (授權類型除外)、重複參數、包含多個憑證、使用多種機制向 GTAF 驗證,或格式有誤。 |
HTTP 401 | invalid_client | 用戶端驗證失敗 (例如:用戶端不明、未納入用戶端驗證,或驗證方法不受支援)。OAuth 伺服器可能會傳回 HTTP 401 (未授權) 狀態碼,指出支援的 HTTP 驗證機制。如果用戶端嘗試透過「Authorization」要求標頭欄位進行驗證,OAuth 伺服器必須傳回 HTTP 401 (未獲授權) 狀態碼,並加入與用戶端所用驗證機制相符的「WWW-Authenticate」回應標頭欄位。 |
HTTP 500 | OAuth 伺服器故障 |