如何對 CloudFront 中已簽署 URL 或 Cookie 相關問題進行疑難排解?

上次更新日期:2022 年 6 月 2 日

我正在使用 Amazon CloudFront 以及已簽署 URL 或已簽署 Cookie 來保護私有內容。並且收到 403 存取遭拒錯誤。如何對此錯誤進行疑難排解?

簡短描述

如果已簽署 URL已簽署 Cookie 發生問題,Amazon CloudFront 可能會傳回 403 存取遭拒錯誤。如需此錯誤的原因及疑難排解步驟,請參閱下列解決方案章節。

解決方案

當您在行為中開啟 Restrict Viewer Access (限制檢視者存取權) 時,必須確定簽署者。簽署者可以是您在 CloudFront 中建立的可信金鑰群組,或是包含 CloudFront 金鑰對的 AWS 帳戶。下列 403 錯誤訊息指示簽署者資訊遺失或不正確:

403 Access Denied (403 存取遭拒) 錯誤且顯示訊息 "Missing Key-Pair-Id query parameter or cookie value." (遺失金鑰對 ID 查詢參數或 Cookie 值。)

此訊息指示已簽署 URL 中的查詢字串參數 Key-Pair-ID 遺失或為空。

403 Access Denied (403 存取遭拒) 錯誤且顯示訊息 "Missing Key-Pair-Id query parameter or cookie value." (遺失金鑰對 ID 查詢參數或 Cookie 值。)

此訊息指示已簽署 Cookie 中的查詢字串參數 CloudFront-Key-Pair-ID 遺失或為空。

403 Access Denied (403 存取遭拒) 錯誤訊息 "Unknown Key." (未知金鑰。)

此訊息指示 CloudFront 無法透過 Key-Pair-ID (針對已簽署 URL) 或 CloudFront-Key-Pair-ID (針對已簽署 Cookie) 來驗證簽署者資訊。若要解決此問題,請確認已簽署 URL 使用了正確的 Key-Pair-ID 值,或者已簽署 Cookie 使用了正確的 CloudFront-Key-Pair-ID 值。首先︰

如果您正在使用已簽署 URL,請尋找並記錄 Key-Pair-ID 的值。
-或-
如果您正在使用已簽署 Cookie,請尋找並記錄 CloudFront-Key-Pair-ID 的值。

然後,尋找金鑰 ID 並確認其與 Key-Pair-IDCloudFront-Key-Pair-ID 相符︰

  1. 開啟 CloudFront 主控台。在左側導覽窗格中,選擇 Distributions (分發)。
  2. 選擇您的分發。然後,選擇 Behaviors (行為) 索引標籤。
  3. 選取行為名稱,然後選擇 Edit (編輯)。
  4. 尋找 Restrict viewer access (限制檢視者存取權) 設定。
    注意:如果設定為 Yes (是),則請求與此快取行為路徑模式相符的檔案必須使用已簽署 URL 或已簽署 Cookie。
  5. 確認 Restrict view access (限制檢視存取權) 欄位設定為 Yes (是) 之後,請檢查 Trusted authorization type (可信授權類型) 欄位。
  6. 如果 Trusted authorization type (可信授權類型) 設定的值為 Trusted key groups (可信金鑰群組),則請記錄可信金鑰群組的名稱。
    然後,尋找可信金鑰群組的公有金鑰 ID:返回 CloudFront 主控台。選擇 Key Groups (金鑰群組)。在金鑰群組清單中,選擇您記錄可信金鑰群組名稱。
    確認您在步驟 1 中記錄的 Key-Pair-Id or CloudFront-Key-Pair-Id 值,與可信金鑰群組中的其中一個公有金鑰 ID 相符。
  7. 如果 Trusted authorization (可信授權類型) 的值為 Trusted Signer (可信簽署者),則會使用 AWS 產生的 CloudFront 憑證。在此情況下,您在步驟 1 中記錄的 Key-Pair-IdCloudFront-Key-Pair-Id 值必須與 CloudFront 憑證的存取金鑰 ID 相符。
    若要尋找 CloudFront 憑證的存取金鑰 ID,請參閱為簽署者建立金鑰對

當您建立已簽署 URL 或已簽署 Cookie 時,JSON 格式的政策陳述式會指定對已簽署 URL 的限制。此陳述式確定 URL 的有效時長。如果出現以下情況,則 CloudFront 將傳回 403 存取遭拒錯誤:

  • 使用標準政策時,已簽署 URL 的傳送時間大於已簽署 URL 中的 Expires 值。
  • 使用標準政策時,已簽署 Cookie 的傳送時間大於已簽署 Cookie 中的 CloudFront-Expires 值。
  • 使用自訂政策時,已簽署 URL 或已簽署 Cookie 的傳送時間大於 DateLessThan 值或小於 DateGreaterThan 值。

注意ExpiresCloudFront-ExpiresDateLessThanDateGreaterThan 中的值採用 Unix 時間格式 (以秒為單位) 和國際標準時間 (UTC)。例如,2013 年 1 月 1 日上午 10:00 (世界標準時間) 會以 Unix 時間格式轉換為 1357034400。如果使用紀元時間,請在不晚於 2147483647 (2038 年 1 月 19 日下午 03:14:07 UTC ) 的日期使用 32 位元整數。

已簽署 URL 中的 Policy 參數或已簽署 Cookie 中的 CloudFront-Policy 屬性指示使用自訂政策。政策陳述式採用 JSON 格式,並以 base64 編碼。若要找出 DateLessThanDateGreaterThan 的值,請使用 64base 解碼命令。

base64 編碼自訂政策的範例如下所示:

eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2QxMTExMTFhYmNkZWY4LmNsb3VkZnJvbnQubmV0L2dhbWVfZG93bmxvYWQuemlwIiwiQ29uZGl0aW9uIjp7IklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIxOTIuMC4yLjAvMjQifSwiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MjY1MDAwMDB9fX1dfQ__

使用下列 Linux 命令,將 base64 編碼格式的自訂政策解碼為 JSON 格式。此範例使用上一個範例中的值。以您自己的自訂政策取代。

$ echo -n eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2QxMTExMTFhYmNkZWY4LmNsb3VkZnJvbnQubmV0L2dhbWVfZG93bmxvYWQuemlwIiwiQ29uZGl0aW9uIjp7IklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIxOTIuMC4yLjAvMjQifSwiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MjY1MDAwMDB9fX1dfQ__ | base64 -di

命令的輸出看起來類似下列內容:

{ "Statement": [{ "Resource": "http://d111111abcdef8.cloudfront.net/game_download.zip", "Condition": { "IpAddress": { "AWS:SourceIp": "192.0.2.0/24" }, "DateLessThan": { "AWS:EpochTime": 1426500000 } } }] }

如果標準政策或自訂政策中包含多個陳述式,CloudFront 將傳回 403 存取遭拒錯誤。

若要進行疑難排解,請使用前一節中的 Linux 命令來檢查自訂政策的陳述式。驗證您的程式碼詳細資料,並確認標準政策或自訂政策中只包含一個陳述式。

如果出現以下情況,則 CloudFront 將傳回 403 存取遭拒錯誤:

  • 政策陳述式金鑰資源中的基本 URL 具有縮寫 URL (www.example.com)。請使用完整的 URL (http://www.example.com)。
  • 基本 URL 沒有 UTF-8 字元編碼。
  • 基本 URL 不包含所有標點符號和參數名稱。
  • 基本 URL 中的 HTTP 或 HTTPS 協定與傳送已簽署 URL 或已簽署 Cookie 請求中使用的協定不相符。
  • 基本 URL 中的網域名稱與傳送已簽署 URL 或已簽署 Cookie 的使用者代理程式使用的託管標頭值不相符。
  • 基本 URL 查詢字串包含無效的字元。

如果出現以下情況,則 CloudFront 將傳回 403 存取遭拒錯誤:

  • 政策陳述式包含空格 (包括索引標籤和新行字元)。
  • 在進行雜湊處理之前,標準政策或自訂政策並未格式化為字串。如果您在不使用 AWS SDK 的情況下建立已簽署 URL 或已簽署 Cookie,則可能會發生這種情況。
  • 在產生簽章之前,政策並未進行雜湊處理。如果您在不使用 AWS SDK 的情況下建立已簽署 URL 或已簽署 Cookie,則可能會發生這種情況。

如需使用已簽署 URL 或已簽署 Cookie 時的簽章最佳實務,請參閱 建立已簽署 URL 簽章的程式碼範例

如果出現以下情況,則 CloudFront 將傳回 403 存取遭拒錯誤:

  • 已簽署 URL 或已簽署的 Cookie 從 IPv6 IP 地址傳送。
  • 已簽署 URL 或已簽署 Cookie 未從自訂政策中指定的 IPv4 地址或 IPv4 IP 範圍傳送。

金鑰 IpAddress 只能在已簽署 URL 或已簽署 Cookie 中的自訂政策中使用。不支援 IPv6 格式的 IP 地址。如果您正在使用包含 IpAddress 的自訂政策,則不要為分發啟用 IPv6。

如果 Cookie 從 CloudFront 傳回,但未包含在相同網域的以下請求中,則 CloudFront 會傳回 403 存取遭拒錯誤。在這種情況下,請檢查 Set-Cookie 回應標頭中的 Cookie 屬性 Domain (網域) 和 Path (路徑)。

Domain (網域) 值是請求檔案的網域名稱。如果您未指定 Domain (網域) 屬性,則預設值為 URL 中的網域名稱。這僅適用於指定的網域名稱,不適用於子網域。如果您指定 Domain (網域) 屬性,則該屬性也會套用至子網域。

如果您指定 Domain (網域) 屬性,則 URL 中的網域名稱和 Domain (網域) 屬性的值必須相符。您可以指定 CloudFront 指派給您的分發的網域名稱 (例如,d111111abcdef8.cloudfront.net),但無法為網域名稱指定 *.cloudfront.net。若要在 URL 中使用替代網域名稱 (例如 example.com),請在您的分發中新增替代網域名稱

Path (路徑) 值是請求檔案的路徑。如果您未指定 Path (路徑) 屬性,則預設值為 URL 中的路徑。


此文章是否有幫助?


您是否需要帳單或技術支援?