適用於數據方案代理程式的 OAuth

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 伺服器必須能在輪替期間支援兩組憑證,且必須能夠停用憑證。一般憑證輪替程序如下:

  1. 電信業者會在 OAuth 伺服器上建立新憑證,並以安全的方式將憑證提供給技術帳戶管理員。
  2. Google 會測試新憑證,並變更 GTAF 設定以使用新憑證。
  3. Google 會通知電信業者,舊憑證可能會停用。
  4. 電信業者停用憑證並通知 Google
  5. 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 伺服器故障

如要瞭解可用於偵錯的其他回應,請參閱 RFC 6749 第 5.2 節