我该如何解决与 CloudFront 中的签名 URL 或签名 Cookie 相关的问题?

3 分钟阅读
0

我在使用 Amazon CloudFront 和签名 URL 或签名 Cookie 来保护私有内容。但是,我收到 403 访问被拒绝错误。

解决方法

如果 Amazon CloudFront 遇到签名 URL签名 Cookie 问题,您可能会收到 403 访问被拒绝错误。

签名 URL 或签名 Cookie 未包含正确的签名者

当您在某个行为中启用限制查看者访问权限时,必须确定签名者。签名者是您在 CloudFront 中创建的可信密钥组,或者是包含 CloudFront 密钥对的 AWS 账户。以下 403 错误消息指示签名者信息缺失或不正确:

错误包含消息“缺少 Key-Pair-Id 查询参数或 Cookie 值”。

此消息指示使用签名 URL 时 Key-Pair-Id 查询参数缺失或为空。或者,指示签名 Cookie 中缺少 CloudFront-Key-Pair-ID 查询字符串参数。

错误包含消息“未知密钥”。

此消息指示 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 控制台。在导航菜单中,选择分配

2.    选择您的分配。然后,选择行为选项卡。

3.    选择行为名称,然后选择编辑

4.    找到限制查看者访问权限设置。  注意: 如果设置为,则对与此缓存行为的路径模式匹配的文件的请求必须使用签名 URL 或签名 Cookie。

5.    确认限制查看者访问权限字段设置为后,检查可信授权类型字段。

6.    如果可信授权类型值设置为可信密钥组,请记下可信密钥组的名称。
查找可信密钥组的公钥 ID:
打开 CloudFront 控制台。选择密钥组
在密钥组列表中,选择您记下的可信密钥组的名称。
确认您在步骤 1 中记下的 Key-Pair-IdCloudFront-Key-Pair-Id 值与可信密钥组中的其中一个公钥 ID 匹配。

7.    如果可信授权类型的值为可信签名者,CloudFront 将使用 AWS 生成的凭证。在这种情况下,您在步骤 1 中记下的 Key-Pair-IdCloudFront-Key-Pair-Id 的值必须与 CloudFront 凭证的访问密钥 ID 匹配。  要查找 CloudFront 凭证的访问密钥 ID,请参阅为签名者创建密钥对

签名 URL 或签名 Cookie 未在有效时间内发送

当您创建签名 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 点 UTC 将转换为 Unix 时间格式的 1357034400。如果您使用纪元时间,则使用 32 位整数表示不晚于 2147483647(2038 年 1 月 19 日 03:14:07 UTC)的日期。

签名 URL 中的 Policy 参数或签名 Cookie 中的 CloudFront-Policy 属性指示您使用的是自定义策略。策略声明采用 JSON 格式和 base64 编码。要找出 DateLessThanDateGreaterThan 值,使用 64base 解码命令。

base64 编码的自定义策略示例:

eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2QxMTExMTFhYmNkZWY4LmNsb3VkZnJvbnQubmV0L2dhbWVfZG93bmxvYWQuemlwIiwiQ29uZGl0aW9uIjp7IklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIxOTIuMC4yLjAvMjQifSwiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MjY1MDAwMDB9fX1dfQ__

要将 base64 编码格式的自定义策略解码为 JSON 格式,请运行以下 Linux 命令。此示例使用前一个示例的值。将策略值替换为您自己的自定义策略值。

$ 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 } } }] }

签名 URL 或签名 Cookie 在策略中有多个声明

如果标准策略或自定义策略中包含多个声明,CloudFront 会返回 403 访问被拒绝错误。

要解决此问题,请运行上一部分的 Linux 命令检查自定义策略声明。验证您的代码详细信息,然后确认标准策略或自定义策略中仅包含一个声明。

策略中的签名 URL 或签名 Cookie 的基本 URL 不正确

在以下任何情况下,CloudFront 都会返回 403 访问被拒绝错误:

  • 基本 URL 在策略声明的资源密钥中采用了缩写(www.example.com)。请使用完整 URL(http://www.example.com)。
  • 基本 URL 没有 UTF-8 字符编码。
  • 基本 URL 不包含所有标点符号和参数名称。
  • 基本 URL 中的 HTTP 或 HTTPS 协议与发送签名 URL 或签名 Cookie 的请求中使用的协议不匹配。
  • 基本 URL 的域名与用户代理用来发送签名 URL 或签名 Cookie 的主机标头不匹配。
  • 基本 URL 查询字符串包含无效字符。

策略中的签名 URL 或签名 Cookie 的签名不正确

在以下任何情况下,CloudFront 都会返回 403 访问被拒绝错误:

  • 策略声明包括空格(包括制表符和换行符)。
  • 标准策略或自定义策略在哈希处理之前未设置为字符串格式。如果您是在不使用 AWS SDK 的情况下创建的签名 URL 或签名 Cookie,会发生这种情况。
  • 策略在生成签名之前不会进行哈希处理。如果您是在不使用 AWS SDK 的情况下创建的签名 URL 或签名 Cookie,会发生这种情况。

有关使用签名 URL 或签名 Cookie 的签名最佳做法,请参阅为签名 URL 创建签名的代码示例

签名 URL 或签名 Cookie 从自定义策略中不允许的 IP 地址或 IP 范围发送

在以下任何情况下,CloudFront 都会返回 403 访问被拒绝错误:

  • 签名 URL 或签名 Cookie 从 IPv6 IP 地址发送。
  • 签名 URL 或签名 Cookie 不是从自定义策略中指定的 IPv4 IP 地址或 IPv4 IP 范围发送。

IpAddress 密钥仅在签名 URL 或签名 Cookie 中的自定义策略中可用。不支持 IPv6 格式的 IP 地址。如果您使用包含 IpAddress 的自定义策略,则请勿为分配启用 IPv6。

签名 Cookie 在 Set-cookie 响应标头中不包含“域”和“路径”属性

如果 Cookie 从 CloudFront 返回但未包含在以后发往同一域的请求中,CloudFront 会返回 403 访问被拒绝错误。在这种情况下,请检查 Set-Cookie 响应标头中的路径 Cookie 属性。

值是所请求文件的域名。如果您未指定属性,默认值为 URL 中的域名。这仅适用于指定的域名,不适用于子域。如果您指定属性,它也适用于子域。

如果您指定属性,URL 中的域名和属性的值必须匹配。您可以指定 CloudFront 分配给您的分配的域名(例如,d111111abcdef8.cloudfront.net),但不能指定 *.cloudfront.net 作为域名。要在 URL 中使用备用域名,如 example.com,在您的分配中添加备用域名

路径属性是所请求文件的路径。如果您未指定路径属性,默认值为 URL 中的路径。

AWS 官方
AWS 官方已更新 1 年前