

# 使用自定义策略创建签名 URL
<a name="private-content-creating-signed-url-custom-policy"></a>

要使用自定义策略创建签名 URL，请完成以下步骤。<a name="private-content-creating-signed-url-custom-policy-procedure"></a>

**要使用自定义策略创建签名 URL**

1. 如果您使用 .NET 和 Java 创建签名 URL，而且，如果您尚未将密钥对私有密钥的格式从默认 .pem 格式重新设置为与 .NET 和 Java 兼容的格式，那么现在就开始设置吧。有关更多信息，请参阅 [重新设置私有密钥的格式（仅限 .NET 和 Java）](private-content-trusted-signers.md#private-content-reformatting-private-key)。

1. 连接以下值。您可以使用此示例签名 URL 中的格式。

   

   ```
   https://d111111abcdef8.cloudfront.net/image.jpg?color=red&size=medium&Policy=eyANCiAgICEXAMPLEW1lbnQiOiBbeyANCiAgICAgICJSZXNvdXJjZSI6Imh0dHA6Ly9kemJlc3FtN3VuMW0wLmNsb3VkZnJvbnQubmV0L2RlbW8ucGhwIiwgDQogICAgICAiQ29uZGl0aW9uIjp7IA0KICAgICAgICAgIklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIyMDcuMTcxLjE4MC4xMDEvMzIifSwNCiAgICAgICAgICJEYXRlR3JlYXRlclRoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTI5Njg2MDE3Nn0sDQogICAgICAgICAiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjEyOTY4NjAyMjZ9DQogICAgICB9IA0KICAgfV0gDQp9DQo&Signature=nitfHRCrtziwO2HwPfWw~yYDhUF5EwRunQA-j19DzZrvDh6hQ73lDx~-ar3UocvvRQVw6EkC~GdpGQyyOSKQim-TxAnW7d8F5Kkai9HVx0FIu-5jcQb0UEmatEXAMPLE3ReXySpLSMj0yCd3ZAB4UcBCAqEijkytL6f3fVYNGQI6&Key-Pair-Id=K2JCJMDEHXQW5F&Hash-Algorithm=SHA256
   ```

   删除所有空格（包括制表符和换行符）。您可能需要在应用程序代码的字符串中包括换码符。所有值的类型均为 `String`。  
**1. *文件的基本 URL***  
基本 URL 是您将用于访问文件的 CloudFront URL，如果您不使用签名 URL，包括您自己的查询字符串参数（如果有）。在上一示例中，基本 URL 为 `https://d111111abcdef8.cloudfront.net/image.jpg`。有关适用于分配的 URL 格式的更多信息，请参阅[在 CloudFront 中自定义文件的 URL 格式](LinkFormat.md)。  
以下示例显示了您为分配指定的值。  
   + 以下 CloudFront URL 适用于分配中的图像文件（使用 CloudFront 域名）。请注意，`image.jpg` 是在 `images` 目录中。URL 中文件的路径必须与您的 HTTP 服务器或 Amazon S3 存储桶中文件的路径匹配。

     `https://d111111abcdef8.cloudfront.net/images/image.jpg`
   + 以下 CloudFront URL 包含查询字符串：

     `https://d111111abcdef8.cloudfront.net/images/image.jpg?size=large`
   + 以下 CloudFront URL 适用于分配中的映像文件。两者都使用备用域名，第二个包括查询字符串：

     `https://www.example.com/images/image.jpg`

     `https://www.example.com/images/image.jpg?color=red`
   + 以下 CloudFront URL 用于使用备用域名和 HTTPS 协议的分配中的映像文件：

     `https://www.example.com/images/image.jpg`  
**2.`?`**  
`?` 表示查询字符串参数位于基本 URL 后面。即使您未指定任何查询参数，也应包括 `?`。  
您可以按任意顺序指定以下查询参数。  
**3. *您的查询字符串参数（如果有*`&`**  
（可选）您可以输入自己的查询字符串参数。为此，请在每个参数之间添加一个 & 字符，例如 `color=red&size=medium`。您可以在 URL 中按任意顺序指定查询字符串参数。  
您的查询字符串参数不能命名为 `Policy`、`Signature`、`Key-Pair-Id` 或 `Hash-Algorithm`。
如果您添加自己的参数，请在每个参数后附加 `&`，包括最后一个参数。  
**4. `Policy=`*策略声明的 Base64 编码版本***  
您的策略声明采用 JSON 格式，删除了空格，然后进行 Base64 编码。有关更多信息，请参阅 [为使用自定义策略的签名 URL 创建策略声明](#private-content-custom-policy-statement)。  
策略语句控制签名 URL 授予用户的访问权限。它包括文件的 URL、过期日期和时间、URL 生效的可选日期和时间、允许访问文件的可选 IP 地址或 IP 地址范围。  
**5. `&Signature=`*策略声明经过哈希处理和签署后的版本***  
JSON 策略声明经过哈希处理、签署和 Base64 编码的版本。有关更多信息，请参阅 [为使用自定义策略的签名 URL 创建签名](#private-content-custom-policy-creating-signature)。  
**6. `&Key-Pair-Id=`*CloudFront 公有密钥的公有密钥 ID，您使用该公有密钥的对应私有密钥来生成签名***  
CloudFront 公有密钥的 ID，例如，`K2JCJMDEHXQW5F`。公有密钥 ID 告诉 CloudFront 要使用哪个公有密钥来验证签名的 URL。CloudFront 将比较签名中的信息与策略声明中的信息，以确认该 URL 没有被篡改。  
此公有密钥必须属于作为分配中可信签署人的密钥组。有关更多信息，请参阅 [指定可以创建签名 URL 和签名 Cookie 的签署人](private-content-trusted-signers.md)。  
**7. `&Hash-Algorithm=`*SHA1 或 SHA256***  
（可选）用于创建签名的哈希算法。支持的值为 `SHA1` 和 `SHA256`。如果您未指定该参数，则 CloudFront 默认为 `SHA1`。

## 为使用自定义策略的签名 URL 创建策略声明
<a name="private-content-custom-policy-statement"></a>

要为使用自定义策略的签名 URL 创建策略声明，请完成以下步骤。

有关以各种方式控制访问文件的示例策略声明，请参阅[使用自定义策略的签名 URL 的示例策略声明](#private-content-custom-policy-statement-examples)。<a name="private-content-custom-policy-creating-policy-procedure"></a>

**为使用自定义策略的签名 URL 创建策略声明**

1. 使用以下 JSON 格式构建策略声明。用自己的值替换小于 (`<`) 和大于 (`>`) 符号及其中的描述。有关更多信息，请参阅 [在使用自定义策略的签名 URL 的策略声明中指定的值](#private-content-custom-policy-statement-values)。

   ```
   {
       "Statement": [
           {
               "Resource": "<Optional but recommended: URL of the file>",
               "Condition": {
                   "DateLessThan": {
   	                "AWS:EpochTime": <Required: ending date and time in Unix time format and UTC>
                   },
                   "DateGreaterThan": {
   	                "AWS:EpochTime": <Optional: beginning date and time in Unix time format and UTC>
                   },
                   "IpAddress": {
   	                "AWS:SourceIp": "<Optional: IP address>"
                   }
               }
           }
       ]
   }
   ```

   请注意以下几点：
   + 您只能在策略中包含一个声明。
   + 使用 UTF-8 字符编码。
   + 根据指定，准确包括所有标点符号和参数名称。不接受参数名称的缩写。
   + `Condition` 部分中参数的顺序无关紧要。
   + 有关 `Resource`、`DateLessThan`、`DateGreaterThan` 和 `IpAddress` 值的信息，请参阅[在使用自定义策略的签名 URL 的策略声明中指定的值](#private-content-custom-policy-statement-values)。

1. 删除策略声明中的所有空格（包括制表符和换行符）。您可能需要在应用程序代码的字符串中包括换码符。

1. 使用 MIME Base64 编码对策略声明进行 Base64 编码。有关更多信息，请参阅 *RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies* 中的 [Section 6.8, Base64 Content-Transfer-Encoding](https://tools.ietf.org/html/rfc2045#section-6.8)。

1. 用有效的字符替换 URL 查询字符串中的无效字符。下表列出了无效和有效字符。  
****    
[\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html)

1. 将结果值附在签名 URL `Policy=` 之后。

1. 通过对策略声明进行哈希、签署及 Base64 编码处理，创建签名 URL 的签名。有关更多信息，请参阅 [为使用自定义策略的签名 URL 创建签名](#private-content-custom-policy-creating-signature)。

### 在使用自定义策略的签名 URL 的策略声明中指定的值
<a name="private-content-custom-policy-statement-values"></a>

针对自定义策略创建策略声明时，请指定以下值。

**资源**  
包含任何查询字符串的 URL，但不包括 CloudFront `Policy`、`Signature` 和 `Key-Pair-Id` 和 `Hash-Algorithm` 参数。例如：  
`https://d111111abcdef8.cloudfront.net/images/horizon.jpg\?size=large&license=yes`  
只能为 `Resource` 指定一个 URL 值。  
您可以忽略策略中的 `Resource` 参数，但这样做意味着拥有签名 URL 任何人都可以访问与您用于创建签名 URL 的密钥对相关联的任何**分配中的所有**文件。
请注意以下几点：  
+ **协议** – 该值必须以 `http://`、`https://` 或 `*://` 开头。
+ **查询字符串参数**：如果 URL 有查询字符串参数，请不要使用反斜杠字符（`\`）来转义查询字符串开头的问号字符（`?`）。例如：

  `https://d111111abcdef8.cloudfront.net/images/horizon.jpg?size=large&license=yes`
+ **通配符** – 您可以在策略的 URL 中使用通配符。支持以下通配符：
  + 星号 (`*`)，匹配零个或多个字符
  + 问号 (`?`)，正好匹配一个字符

  当 CloudFront 将策略中的 URL 与 HTTP 请求中的 URL 进行匹配时，策略中的 URL 分为四个部分：协议、域、路径和查询字符串，如下所示：

  `[protocol]://[domain]/[path]\?[query string]`

  当您在策略的 URL 中使用通配符时，通配符匹配仅在包含该通配符的部分的界限内适用。例如，在策略中考虑此 URL:

  `https://www.example.com/hello*world`

  在此示例中，星号通配符 (`*`) 仅适用于路径部分，因此它与 URL `https://www.example.com/helloworld` 和 `https://www.example.com/hello-world` 匹配，但与 URL `https://www.example.net/hello?world` 不匹配。

  以下例外适用于通配符匹配的部分界限：
  + 路径部分中的尾部星号表示查询字符串部分中的星号。例如，`http://example.com/hello*` 等同于 `http://example.com/hello*\?*`。
  + 域部分中的尾部星号表示路径部分和查询字符串部分都有星号。例如，`http://example.com*` 等同于 `http://example.com*/*\?*`。
  + 策略中的 URL 可以忽略协议部分并在域部分中以星号开头。在这种情况下，协议部分被隐式设置为星号。例如，策略中的 URL `*example.com` 等同于 `*://*example.com/`。
  + 星号本身 (`"Resource": "*"`) 与任何 URL 都匹配。

  例如，策略中的值 `https://d111111abcdef8.cloudfront.net/*game_download.zip*` 与以下所有 URL 都匹配：
  + `https://d111111abcdef8.cloudfront.net/game_download.zip`
  + `https://d111111abcdef8.cloudfront.net/example_game_download.zip?license=yes`
  + `https://d111111abcdef8.cloudfront.net/test_game_download.zip?license=temp`
+ **备用域名** – 如果在策略的 URL 中指定备用域名 (CNAME)，则 HTTP 请求必须在网页或应用程序中使用该备用域名。请勿为策略中的文件指定 Amazon S3 URL。

**DateLessThan**  
Unix 时间格式（以秒为单位）和协调通用时间 (UTC) 格式的 URL 过期日期和时间。在策略中，切勿用引号将该值括起来。有关 UTC 的信息，请参阅 [Internet 上的日期和时间：时间戳](https://tools.ietf.org/html/rfc3339)。  
例如，2023 年 1 月 31 日上午 10 点 UTC 转换为 Unix 时间格式就是 1675159200。  
这是 `Condition` 部分唯一需要的参数。CloudFront 需要此值，以防止用户拥有对象的永久访问权。  
有关更多信息，请参阅[CloudFront 何时检查签名 URL 中的过期日期和时间](private-content-signed-urls.md#private-content-check-expiration)

**DateGreaterThan（可选）**  
Unix 时间格式（以秒为单位）和协调通用时间 (UTC) 格式的 URL 可选开始日期和时间。不允许用户在指定日期和时间或之前访问该文件。切勿用引号将该值括起来。

**IpAddress（可选）**  
发出 HTTP 请求的客户端的 IP 地址。请注意以下几点：  
+ 要允许任何 IP 地址访问文件，请省略 `IpAddress` 参数。
+ 可以指定一个 IP 地址或一个 IP 地址范围。如果客户端的 IP 地址在两个独立范围之一的范围内，您不能使用策略来允许访问。
+ 要允许从单个 IP 地址访问，可指定：

  `"`*IPv4 IP 地址*`/32"`
+ 必须采用标准 IPv4 CIDR 格式指定 IP 地址范围（例如，`192.0.2.0/24`）。有关更多信息，请参阅 [Classless Inter-domain Routing (CIDR): The Internet Address Assignment and Aggregation Plan](https://tools.ietf.org/html/rfc4632)。
**重要**  
不支持 IPv6 格式的 IP 地址，如 2001:0db8:85a3::8a2e:0370:7334。

  如果使用包含 `IpAddress` 的自定义策略，请勿为分配启用 IPv6。如果希望通过 IP 地址限制对某些内容的访问并支持其他内容的 IPv6 请求，可以创建两个分配。有关更多信息，请参阅 [启用 IPv6（查看器请求）](DownloadDistValuesGeneral.md#DownloadDistValuesEnableIPv6)主题中的 [所有分配设置参考](distribution-web-values-specify.md)。

## 使用自定义策略的签名 URL 的示例策略声明
<a name="private-content-custom-policy-statement-examples"></a>

以下示例策略声明显示了如何控制对特定文件、目录中的所有文件或与密钥对 ID 有关的所有文件的访问。这些示例也显示了如何控制来自单个 IP 地址或 IP 地址范围的访问，以及如何防止用户在指定日期和时间后使用签名 URL。

如果复制并粘贴其中的任何示例，请删除任何空格（包括制表符和换行符），将值替换为自己的值，并在右大括号（`}`）后面包含一个换行符。

有关更多信息，请参阅 [在使用自定义策略的签名 URL 的策略声明中指定的值](#private-content-custom-policy-statement-values)。

**Topics**
+ [示例策略声明：从 IP 地址范围访问一个文件](#private-content-custom-policy-statement-example-one-object)
+ [示例策略声明：从 IP 地址范围访问一个目录中的所有文件](#private-content-custom-policy-statement-example-all-objects)
+ [示例策略声明：从一个 IP 地址访问与一个密钥对 ID 关联的所有文件](#private-content-custom-policy-statement-example-one-ip)

### 示例策略声明：从 IP 地址范围访问一个文件
<a name="private-content-custom-policy-statement-example-one-object"></a>

签名 URL 中的以下示例自定义策略指定用户可从范围 `192.0.2.0/24` 内的 IP 地址访问文件 `https://d111111abcdef8.cloudfront.net/game_download.zip`，直至 UTC 时间 2023 年 1 月 31 日上午 10 点：

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

### 示例策略声明：从 IP 地址范围访问一个目录中的所有文件
<a name="private-content-custom-policy-statement-example-all-objects"></a>

以下示例自定义策略允许您为 `training` 目录中的任何文件创建签名 URL，如 `Resource` 参数中的星号通配符 (`*`) 所指示。用户可从范围 `192.0.2.0/24` 内的 IP 地址访问文件，直至 UTC 时间 2023 年 1 月 31 日上午 10 点：

```
{
    "Statement": [
        {
            "Resource": "https://d111111abcdef8.cloudfront.net/training/*",
            "Condition": {
                "IpAddress": {
                    "AWS:SourceIp": "192.0.2.0/24"
                },
                "DateLessThan": {
                    "AWS:EpochTime": 1675159200
                }
            }
        }
    ]
}
```

您在其中使用此策略的每个签名 URL 包括确定特定文件的 URL，例如：

`https://d111111abcdef8.cloudfront.net/training/orientation.pdf`

### 示例策略声明：从一个 IP 地址访问与一个密钥对 ID 关联的所有文件
<a name="private-content-custom-policy-statement-example-one-ip"></a>

以下示例自定义策略允许您为与任何分配有关的任何文件创建签名 URL，如 `Resource` 参数中的星号通配符 (`*`) 所指示。签名 URL 必须使用 `https://` 协议，而不是 `http://`。用户必须使用 IP 地址 `192.0.2.10/32`。（CIDR 表示法中的值 `192.0.2.10/32` 指代单个 IP 地址 `192.0.2.10`。） 这些文件仅从 UTC 时间 2023 年 1 月 31 日上午 10 点到 UTC 时间 2023 年 2 月 2 日上午 10 点期间可用：

```
{
    "Statement": [
       {
            "Resource": "https://*",
            "Condition": {
                "IpAddress": {
                    "AWS:SourceIp": "192.0.2.10/32"
                },
                "DateGreaterThan": {
                    "AWS:EpochTime": 1675159200
                },
                "DateLessThan": {
                    "AWS:EpochTime": 1675332000
                }
            }
        }
    ]
}
```

您在其中使用此策略的每个签名 URL 包括确定特定 CloudFront 分配中特定文件的 URL，例如：

`https://d111111abcdef8.cloudfront.net/training/orientation.pdf`

签名 URL 还包括密钥对 ID，它必须与您在 URL 中指定的分配 (d111111abcdef8.cloudfront.net) 中的可信密钥组关联。

## 为使用自定义策略的签名 URL 创建签名
<a name="private-content-custom-policy-creating-signature"></a>

使用自定义策略的签名 URL 的签名是策略声明的哈希、签署及 Base64 编码版本。要为自定义策略创建签名，请完成以下步骤。

有关额外信息以及如何哈希、签署及编码策略声明的示例，请参阅：
+ [用于 Base64 编码和加密的 Linux 命令和 OpenSSL](private-content-linux-openssl.md)
+ [为签名 URL 创建签名的代码示例](PrivateCFSignatureCodeAndExamples.md)

**注意**  
关联的示例默认使用 SHA-1。要改用 SHA-256，请在 OpenSSL 命令中将 `sha1` 替换为 `sha256`，并在签名 URL 中包含 `Hash-Algorithm=SHA256` 查询参数。<a name="private-content-custom-policy-creating-signature-download-procedure"></a>

**选项 1：使用自定义策略创建签名**

1. 使用 SHA-1 或 SHA-256 哈希函数和生成的 RSA 或 ECDSA 私有密钥，对在[为使用自定义策略的签名 URL 创建策略声明](#private-content-custom-policy-creating-policy-procedure)过程中创建的 JSON 策略声明进行哈希处理并签名。使用不再包含空格但尚未进行 Base64 编码的策略声明版本。

   如果您使用 SHA-256，则必须在签名 URL 中包含 `&Hash-Algorithm=SHA256`。

   对于哈希函数所需的私有密钥，请使用其公有密钥位于分配的活动可信密钥组中的私有密钥。
**注意**  
您用于哈希及签署策略声明的方法取决于您的编程语言和平台。有关代码示例，请参阅 [为签名 URL 创建签名的代码示例](PrivateCFSignatureCodeAndExamples.md)。

1. 删除经过哈希处理并签署的字符串中的空格（包括制表符和换行符）。

1. 使用 MIME Base64 编码对字符串进行 Base64 编码。有关更多信息，请参阅 *RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies* 中的 [Section 6.8, Base64 Content-Transfer-Encoding](https://tools.ietf.org/html/rfc2045#section-6.8)。

1. 用有效的字符替换 URL 查询字符串中的无效字符。下表列出了无效和有效字符。  
****    
[\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html)

1. 将结果值附在签名 URL 的 `&Signature=` 之后，然后返回 [要使用自定义策略创建签名 URL](#private-content-creating-signed-url-custom-policy-procedure)，以完成签名 URL 的各部分的串连。