

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 将 Amazon SNS 通知扇出到 HTTPS 端点
<a name="sns-http-https-endpoint-as-subscriber"></a>

您可以使用 Amazon SNS 向一个或多个 HTTP 或 HTTPS 端点发送通知消息。为终端节点订阅主题时，您可以向主题发布通知，Amazon SNS 将发送 HTTP POST 请求，向已订阅终端节点传递通知内容。订阅终端节点时，您可以选择 Amazon SNS 是否使用 HTTP 或 HTTPS 向终端节点发送 POST 请求。如果您使用 HTTPS，则可以利用 Amazon SNS 对以下功能的支持：
+ **服务器名称指示 (SNI)** - 这使 Amazon SNS 可以支持需要 SNI 的 HTTPS 终端节点，如需要多个证书来承载多个域的服务器。有关 SNI 的更多信息，请参阅[服务器名称指示](http://en.wikipedia.org/wiki/Server_Name_Indication)。
+ **基本和摘要式访问身份验证** - 这使您可以在 HTTPS URL 中为 HTTP POST 请求指定用户名和密码，如 `https://user:password@domain.com` 或 `https://user@domain.com`。在使用 HTTPS 建立的 SSL 连接上，会对该用户名和密码进行加密。只有域名以明文形式发送。有关基本和摘要式访问身份验证的更多信息，请参阅 [RFC-2617](http://www.rfc-editor.org/info/rfc2617)。
**重要**  
Amazon SNS 目前不支持私有 HTTP(S) 端点。  
对于您 URLs 已授予 API 访问权限的委托人，只能从 Amazon `GetSubscriptionAttributes` SNS API 操作中检索 HTTPS。
**注意**  
 客户端服务必须能够支持 `HTTP/1.1 401 Unauthorized` 标头响应

此项请求包含已向主题发布的相关主题和消息，包括 JSON 文档中通知的元数据。此项请求与以下 HTTP POST 请求相似。有关 HTTP 标头和请求正文 JSON 格式的详细信息，请参阅 [HTTP/HTTPS 标题](http-header.md) 和 [HTTP/HTTPS 通知 JSON 格式](http-notification-json.md)。

**注意**  
Amazon SNS 将所有 5XX 错误和 429（发送的请求过多）错误视为可重试错误。这些错误会按照传输策略进行重试。其他所有错误都被视为永久失败，不会进行重试。

```
POST / HTTP/1.1
    x-amz-sns-message-type: Notification
    x-amz-sns-message-id: da41e39f-ea4d-435a-b922-c6aae3915ebe
    x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
    x-amz-sns-subscription-arn: arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55
    Content-Length: 761
    Content-Type: text/plain; charset=UTF-8
    Host: ec2-50-17-44-49.compute-1.amazonaws.com
    Connection: Keep-Alive
    User-Agent: Amazon Simple Notification Service Agent
    
{
  "Type" : "Notification",
  "MessageId" : "da41e39f-ea4d-435a-b922-c6aae3915ebe",
  "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
  "Subject" : "test",
  "Message" : "test message",
  "Timestamp" : "2012-04-25T21:49:25.719Z",
  "SignatureVersion" : "1",
  "Signature" : "EXAMPLElDMXvB8r9R83tGoNn0ecwd5UjllzsvSvbItzfaMpN2nk5HVSw7XnOn/49IkxDKz8YrlH2qJXj2iZB0Zo2O71c4qQk1fMUDi3LGpij7RCW7AW9vYYsSqIKRnFS94ilu7NFhUzLiieYr4BKHpdTmdD6c0esKEYBpabxDSc=",
  "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
   "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55"
}
```

# 为 HTTPS 端点订阅 Amazon SNS 主题
<a name="sns-subscribe-https-s-endpoints-to-topic"></a>

本主题介绍如何为 HTTP/S 终端节点订阅 Amazon SNS 主题。

**Topics**
+ [步骤 1：确保您的终端节点已准备好处理 Amazon SNS 消息](SendMessageToHttp.prepare.md)
+ [步骤 2：为 HTTP/HTTPS 终端节点订阅 Amazon SNS 主题](SendMessageToHttp.subscribe.md)
+ [第 3 步：确认您的 Amazon SNS 订阅](SendMessageToHttp.confirm.md)
+ [步骤 4：可选 - 设置 Amazon SNS 订阅的传送策略](SendMessageToHttp.retry.md)
+ [步骤 5：可选 - 授予用户发布 Amazon SNS 主题的权限](SendMessageToHttp.iam.permissions.md)
+ [步骤 6：向终端节点发送 Amazon SNS 消息 HTTP/HTTPS](SendMessageToHttp.publish.md)

# 步骤 1：确保您的终端节点已准备好处理 Amazon SNS 消息
<a name="SendMessageToHttp.prepare"></a>

确保供 Amazon SNS 使用发送订阅确认和通知消息的 HTTP 或 HTTPS 终端节点能够处理 HTTP POST 请求之后，方可订阅相关主题的 HTTP 或 HTTPS 终端节点。一般情况下，这要求创建和部署 Web 应用程序（例如，若您的终端主机正在通过 Apache 和 Tomcat 运行 Linux，则为 Java servlet），用于处理来自 Amazon SNS 的 HTTP 请求。当您订阅 HTTP 终端节点时，Amazon SNS 会向其发送一条订阅确认请求。当您创建订阅时，终端节点必须已经准备好接收和处理此请求，因为 Amazon SNS 会同时发送此请求。在您确认订阅前，Amazon SNS 不会向终端节点发送消息。订阅确认后，在已订阅主题上执行发布操作时，Amazon SNS 会向终端节点发送通知。

**设置您的终端节点，处理订阅确认和通知消息**

1. 您的代码将读取 Amazon SNS 向您的终端节点发送的 HTTP POST 请求的 HTTP 标头。您的代码将查找标头字段 `x-amz-sns-message-type`，此标头字段将显示 Amazon SNS 向您发送的消息类型。查看标头后，您可以确定消息类型，而无需分析 HTTP 请求正文。您需要处理如下两种类型消息：`SubscriptionConfirmation` 和 `Notification`。仅当从主题中删除订阅时，方使用 `UnsubscribeConfirmation` 消息。

   有关 HTTP 标头的详细信息，请参阅 [HTTP/HTTPS 标题](http-header.md)。以下 HTTP POST 请求为订阅确认消息的一个示例。

   ```
   POST / HTTP/1.1
       x-amz-sns-message-type: SubscriptionConfirmation
       x-amz-sns-message-id: 165545c9-2a5c-472c-8df2-7ff2be2b3b1b
       x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
       Content-Length: 1336
       Content-Type: text/plain; charset=UTF-8
       Host: example.com
       Connection: Keep-Alive
       User-Agent: Amazon Simple Notification Service Agent
       
   {
     "Type" : "SubscriptionConfirmation",
     "MessageId" : "165545c9-2a5c-472c-8df2-7ff2be2b3b1b",
     "Token" : "2336412f37f...",
     "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
     "Message" : "You have chosen to subscribe to the topic arn:aws:sns:us-west-2:123456789012:MyTopic.\nTo confirm the subscription, visit the SubscribeURL included in this message.",
     "SubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:123456789012:MyTopic&Token=2336412f37...",
     "Timestamp" : "2012-04-26T20:45:04.751Z",
     "SignatureVersion" : "1",
     "Signature" : "EXAMPLEpH+...",
     "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem"
   }
   ```

1. 您的代码应解析 HTTP POST 请求正文中的 JSON 文档和内容类型， text/plain 以读取构成 Amazon SNS 消息的名称/值对。使用 JSON 分析器将控制字符的转义字符转换回 ASCII 字符值（例如，将 \$1n 转换成换行符）。您可以使用现有 JSON 分析器（例如 [Jackson JSON 处理器](https://github.com/FasterXML/jackson)）或者由您自己写入。要将主题和消息字段中的文本作为有效 JSON 发送，Amazon SNS 必须将部分控制字符转换成可包含在 JSON 文档中的转义字符。向您的终端节点发送的 POST 请求正文中包括 JSON 文档，当您接收到该文档时，若您想要获取发布到主题上的原始主题和消息的精确字符，则必须将转义字符转换回其原始字符值。由于签名采用了原始形式的消息和主题作为待签字符串的一部分，因此如果您想要验证通知签名，则上述操作非常重要。

1. 您的代码应对 Amazon SNS 发送的通知、订阅确认或取消订阅确认消息进行验证。使用 Amazon SNS 消息所含信息，终端节点可以重新创建签名，以便您可以通过将自己的签名与 Amazon SNS 随消息发送的签名进行匹配，来验证消息的内容。有关验证消息签名的更多信息，请参阅 [验证 Amazon SNS 消息签名](sns-verify-signature-of-message.md)。

1. 根据标头字段 `x-amz-sns-message-type` 指定的类型，您的代码将读取 HTTP 请求正文所含的 JSON 文档，并处理该消息。这里是处理两大主要消息类型的指导原则：  
**SubscriptionConfirmation**  
读取 `SubscribeURL` 值，访问此 URL。要确认订阅并通过此终端节点接收通知，必须访问 `SubscribeURL` URL（例如，向此 URL 发送 HTTP GET 请求）。参阅上一步中 HTTP 请求示例，查看 `SubscribeURL` 相关情况。有关 `SubscriptionConfirmation` 消息格式的更多信息，请参阅 [HTTP/HTTPS 订阅确认 JSON 格式](http-subscription-confirmation-json.md)。访问 URL 时，您将获取与以下 XML 文档相似的响应。文档会在 `ConfirmSubscriptionResult` 元素内返回终端节点的订阅 ARN。  

   ```
   <ConfirmSubscriptionResponse xmlns="http://sns.amazonaws.com/doc/2010-03-31/">
      <ConfirmSubscriptionResult>
         <SubscriptionArn>arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55</SubscriptionArn>
      </ConfirmSubscriptionResult>
      <ResponseMetadata>
         <RequestId>075ecce8-8dac-11e1-bf80-f781d96e9307</RequestId>
      </ResponseMetadata>
   </ConfirmSubscriptionResponse>
   ```
除了访问之外`SubscribeURL`，您还可以使用在`SubscriptionConfirmation`消息中`Token`设置相应值的[ConfirmSubscription](https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html)操作来确认订阅。如果您仅允许主题所有者和订阅所有者拥有取消订阅终端节点的权限，那么您可以通过 AWS 签名调用 `ConfirmSubscription` 操作。  
**通知**  
读取 `Subject` 和 `Message` 值，获取已向主题发布的通知信息。  
有关 `Notification` 消息格式的详细信息，请参阅 [HTTP/HTTPS 标题](http-header.md)。以下 HTTP POST 请求为向终端节点 example.com.发送的通知消息的示例。  

   ```
   POST / HTTP/1.1
       x-amz-sns-message-type: Notification
       x-amz-sns-message-id: 22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324
       x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
       x-amz-sns-subscription-arn: arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96
       Content-Length: 773
       Content-Type: text/plain; charset=UTF-8
       Host: example.com
       Connection: Keep-Alive
       User-Agent: Amazon Simple Notification Service Agent
       
   {
     "Type" : "Notification",
     "MessageId" : "22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324",
     "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
     "Subject" : "My First Message",
     "Message" : "Hello world!",
     "Timestamp" : "2012-05-02T00:54:06.655Z",
     "SignatureVersion" : "1",
     "Signature" : "EXAMPLEw6JRN...",
     "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
     "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96"
   }
   ```

1. 确保您的终端节点已通过适当的状态代码对来自 Amazon SNS 的 HTTP POST 消息作出响应。此项连接将在大约 15 秒内超时。在连接超时前，如果您的端点不响应，或者您的端点返回的状态代码超出 200–4*xx* 范围，那么 Amazon SNS 会认为消息发送尝试失败。

1. 确保您的代码能够处理 Amazon SNS 的消息发送重试。如果 Amazon SNS 未能接收到从终端节点发出的发送成功响应，它将会尝试再次发送消息。这适用于包括订阅确认消息在内的所有消息。默认情况下，如果消息初次发送失败，那么 Amazon SNS 会通过失败尝试期间设定为 20 秒的延时进行多达 3 次的尝试。
**注意**  
消息请求大约 15 秒后超时。这表示，如果因超时引起消息发送失败，那么 Amazon SNS 将在前一次发送尝试后 35 秒左右重新发送。您可以为终端节点设置不同的发送策略。

   Amazon SNS 使用 `x-amz-sns-message-id` 标头字段来唯一标识发布到 Amazon SNS 主题的每条消息。通过将已处理 IDs 的消息与传入的消息进行比较，可以确定该消息是否为重试尝试。

1. 如果您要订阅 HTTPS 终端节点，请确保终端节点具备由可信赖证书颁发机构 (CA) 颁发的服务器证书。 将仅向具有 所信任 CA 签署的服务器证书的 HTTPS 终端节点发送消息。Amazon SNS 将仅向具有 Amazon SNS 所信任 CA 签署的服务器证书的 HTTPS 终端节点发送消息。

1. 对您已创建的代码进行部署，以便接收 Amazon SNS 消息。当您订阅终端节点时，该终端节点必须准备好至少接收订阅确认消息。

# 步骤 2：为 HTTP/HTTPS 终端节点订阅 Amazon SNS 主题
<a name="SendMessageToHttp.subscribe"></a>

要通过主题向 HTTP 或 HTTPS 终端节点发送消息，必须为终端节点订阅 Amazon SNS 主题。您可以通过终端节点的 URL 指定终端节点。要订阅主题，您可以使用 Amazon SNS 控制台、[sns-subscribe](https://docs.aws.amazon.com/cli/latest/reference/sns/subscribe.html) 命令或 [Subscribe](https://docs.aws.amazon.com/sns/latest/api/API_Subscribe.html) API 操作。开始操作前，应确保拥有想要订阅终端节点的 URL，并且该终端节点按照步骤 1 所述已准备好接收确认和通知消息。

**利用 Amazon SNS 控制台为 HTTP 或 HTTPS 终端节点订阅主题**

1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

1. 在导航面板中，选择**订阅**。

1. 选择 **Create subscription**（创建订阅）。

1. 在 **Protocol** 下拉列表中，选择 **HTTP** 或 **HTTPS**。

1. 在**终端节点**框中，粘贴您希望主题向其发送消息的终端节点的 URL，然后选择**创建订阅**。

1. 将显示确认消息。选择**关闭**。

   将显示您的新订**阅的订阅 ID** PendingConfirmation。当您确认订阅时，**Subscription ID (订阅 ID)** 将显示订阅 ID。

# 第 3 步：确认您的 Amazon SNS 订阅
<a name="SendMessageToHttp.confirm"></a>

要确认您的 Amazon SNS 订阅，请按照以下步骤操作，确保您的端点能够成功接收消息。此过程包括设置端点以处理传入的确认消息、检索确认 URL 以及确认订阅。您可以自动或手动确认订阅，具体取决于您的设置。

1. 订阅到 Amazon SNS 主题后，Amazon SNS 会向您的端点发送一条订阅确认消息。此消息包含 `SubscribeURL`，您必须用它来确认订阅。

1. 您的端点必须设置为监听来自 Amazon SNS 的传入消息。当确认消息到达时，从消息中提取 **`SubscribeURL`**。

1. 获得 `SubscribeURL` 后，您可以通过下列两种方式之一确认订阅：
   + **自动确认**：您的端点可以通过向 `SubscribeURL` 发送 **HTTP GET 请求**来自动确认订阅。

     此方法不需要手动干预。
   + **手动确认**：如果未设置自动确认，请**复制**确认消息中的 **`SubscribeURL`**，然后将其**粘贴**到浏览器的地址栏中。

     这将手动确认订阅。

1. 您还可以使用 Amazon SNS 控制台验证**订阅状态**。

   1. 登录 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/home)。

   1. 在导航窗格中，选择**订阅**。

   1. 在列表中找到您的**订阅**。
      + 如果已确认，`SubscriptionArn` 将显示。
      + 如果仍未确认，它将显示为 `PendingConfirmation`。

# 步骤 4：可选 - 设置 Amazon SNS 订阅的传送策略
<a name="SendMessageToHttp.retry"></a>

默认情况下，如果消息初次发送失败，那么 Amazon SNS 会通过失败尝试期间设定为 20 秒的延时进行多达 3 次的尝试。按照[步骤 1](SendMessageToHttp.prepare.md) 所述，您的终端节点应包括能够处理已重试消息的代码。通过设置主题或订阅的发送策略，您可以控制 Amazon SNS 即将重试失败消息的频率和间隔。您还可以在中指定 HTTP/S 通知的内容类型`DeliveryPolicy`。有关更多信息，请参阅 [创建配 HTTP/S 送策略](sns-message-delivery-retries.md#creating-delivery-policy)。

# 步骤 5：可选 - 授予用户发布 Amazon SNS 主题的权限
<a name="SendMessageToHttp.iam.permissions"></a>

默认情况下，只有主题所有者才拥有发布主题的权限。要允许其他用户或应用程序向该主题发布内容，您应使用 AWS Identity and Access Management (IAM) 授予该主题的发布权限。有关授予 IAM 用户 Amazon SNS 操作权限的更多信息，请参阅 [将基于身份的策略用于 Amazon SNS](sns-using-identity-based-policies.md)。

可以采取两种方式控制对主题的访问：
+ 添加策略至 IAM 用户或群组。向用户授予主题权限的最简单方式就是创建群组，向该群组添加适当策略，再向此群组添加用户。相比较而言，向群组添加或删除用户，比追踪您为单独用户而设定的各项策略要简单得多。
+ 添加策略至主题。如果您想向另一 AWS 账户授予主题权限，那么唯一的方法是添加策略，并且该策略必须具备您想向其授予权限的主要 AWS 账户 。

绝大多数情况下，您应使用第一种方法（通过向群组添加或删除适当用户的方式，向群组添加策略，管理用户权限）。如果您需要向另一账户的用户授予权限，请使用第二种方法。

如果您向 IAM 用户或群组添加了以下策略，则需要向该用户或群组中的成员授予对该主题执行`sns:Publish`操作的权限 MyTopic。

```
{
  "Statement":[{
    "Sid":"AllowPublishToMyTopic",
    "Effect":"Allow",
    "Action":"sns:Publish",
    "Resource":"arn:aws:sns:us-east-2:123456789012:MyTopic"
  }]
}
```

以下策略示例显示如何向主题授予另一账户权限。

**注意**  
当您授予其他人 AWS 账户 访问您账户中某项资源的权限时，也就是向对该资源拥有管理员级访问权限（通配符访问权限）的 IAM 用户授予权限。此操作将自动拒绝其他账户中的所有其他 IAM 用户访问您的资源。如果您想向该中的特定 IAM 用户授予 AWS 账户 访问您的资源的权限，则该账户或具有管理员级别访问权限的 IAM 用户必须将资源权限委托给这些 IAM 用户。有关跨账户委派的更多信息，请参阅*使用 IAM 指南*中的[启用跨账户访问](https://docs.aws.amazon.com/IAM/latest/UserGuide/Delegation.html)。

如果您向账户 123456789012 MyTopic 中的某个主题添加了以下策略，则需要向账户 111122223333 授予对该主题执行操作的权限。`sns:Publish`

```
{
  "Statement":[{
    "Sid":"Allow-publish-to-topic",
    "Effect":"Allow",
      "Principal":{
        "AWS":"111122223333"
      },
    "Action":"sns:Publish",
    "Resource":"arn:aws:sns:us-east-2:123456789012:MyTopic"
  }]
}
```

# 步骤 6：向终端节点发送 Amazon SNS 消息 HTTP/HTTPS
<a name="SendMessageToHttp.publish"></a>

您可以通过发布到主题来向主题订阅发送消息。要订阅主题，您可以使用 Amazon SNS 控制台、`[sns-publish](https://docs.aws.amazon.com/cli/latest/reference/sns/publish.html)` CLI 命令或 `[Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html)` API。

如果您遵循 [步骤 1](SendMessageToHttp.prepare.md)，则在您的终端节点上部署的代码将处理通知。

**利用 Amazon SNS 控制台发布主题**

1. 使用有权发布主题的 AWS 账户 或 IAM 用户的证书，登录 AWS 管理控制台 并打开 Amazon SNS 控制台，网址为。[https://console.aws.amazon.com/sns/](https://console.aws.amazon.com/sns/home)

1. 在导航面板上，选择**主题**，然后选择一个主题。

1. 选择**发布消息**按钮。

1. 在**主题**框中，输入主题（例如，**Testing publish to my endpoint**）。

1. 在**消息**框中，输入一些文本（例如 **Hello world\$1**），然后选择 **发布消息**。

    界面将显示如下消息：Your message has been successfully published。

# 验证 Amazon SNS 消息签名
<a name="sns-verify-signature-of-message"></a>

Amazon SNS 使用消息签名来确认发送到您的 HTTP 端点的消息的真实性。为确保消息完整性并防止欺骗，您**必须**在处理任何 Amazon SNS 消息之前验证签名。

**什么时候应该验证 Amazon SNS 签名？**

在以下情况下，您应该验证 Amazon SNS 消息签名：
+ Amazon SNS 将通知消息发送到您的 HTTP(S) 端点时。
+ 当 Amazon SNS 在 [https://docs.aws.amazon.com/sns/latest/api/API_Subscribe.html](https://docs.aws.amazon.com/sns/latest/api/API_Subscribe.html) 或 [https://docs.aws.amazon.com/sns/latest/api/API_Unsubscribe.html](https://docs.aws.amazon.com/sns/latest/api/API_Unsubscribe.html) API 调用后向您的端点发送确认消息时。

**Amazon SNS 支持两种消息签名版本：**
+ SignatureVersion1-使用消息的SHA1哈希值。
+ SignatureVersion2-使用消息的SHA256哈希值。这提供了更强的安全性，推荐使用该选项。

**要正确验证 SNS 消息签名，请遵循以下最佳实践：**
+ 请务必使用 HTTPS 检索签名证书，以防止未经授权的拦截攻击。
+ 检查证书是否由 Amazon SNS 签发。
+ 确认证书的信任链有效。
+ 证书应来自 SNS 签名的 URL。
+ 未经验证，请勿信任消息中提供的任何证书。
+ 拒绝任何带有意外 `TopicArn` 的消息，以防止欺骗。
+  AWS SDKs 适用于 Amazon SNS 的提供了内置的验证逻辑，从而降低了错误实施的风险。

# 在 Amazon SNS 主题上配置消息签名版本
<a name="sns-verify-signature-of-message-configure-message-signature"></a>

通过在 Amazon SNS 主题中配置消息签名版本，您可以增强消息验证流程的安全性和兼容性。

在 `SignatureVersion` **1** (SHA1) 和 `SignatureVersion` **2** (SHA256) 之间进行选择，以控制用于签名消息的哈希算法。默认情况下，Amazon SNS 主题使用 `SignatureVersion`**1**。您可以使用 [https://docs.aws.amazon.com/sns/latest/api/API_SetTopicAttributes.html](https://docs.aws.amazon.com/sns/latest/api/API_SetTopicAttributes.html) API 操作配置此设置。

参照以下示例使用 AWS CLI设置主题属性 `SignatureVersion`：

```
aws sns set-topic-attributes \
    --topic-arn arn:aws:sns:us-east-2:123456789012:MyTopic \
    --attribute-name SignatureVersion \
    --attribute-value 2
```

# 在使用基于 HTTP 查询的请求时验证 Amazon SNS 消息的签名
<a name="sns-verify-signature-of-message-verify-message-signature"></a>

在使用基于 HTTP 查询的请求时验证 Amazon SNS 消息的签名，可确保消息的真实性和完整性。此过程确认消息源自 Amazon SNS，并且在传输过程中未被篡改。通过解析消息、构造正确的签名字符串以及根据可信的公有密钥验证签名，可以保护您的系统免受欺骗和未经授权的消息更改。

1. 从 Amazon SNS 发送的 HTTP POST 请求正文的 JSON 文档中提取**键值对**。这些字段是构造**待签字符串**所必需的。
   + `Message`
   + `Subject`（如果存在）
   + `MessageId`
   + `Timestamp`
   + `TopicArn`
   + `Type`

   例如：

   ```
   MESSAGE_FILE="message.json"
   FIELDS=("Message" "MessageId" "Subject" "Timestamp" "TopicArn" "Type")
   ```
**注意**  
如果任何字段包含转义字符（例如 `\n`），请将其转换为其**原始形式**以确保完全匹配。

1. 在 Amazon SNS 消息中找到 `SigningCertURL` 字段。该证书包含验证消息签名所需的公有密钥。例如：

   ```
   SIGNING_CERT_URL=$(jq -r '.SigningCertURL' "$MESSAGE_FILE")
   ```

1. 确保来自`SigningCertURL`可信 AWS 域（例如，https://sns.us-east-1.amazonaws.com）。出于安全考虑，拒绝任何 URLs **外部 AWS 域名**。

1. 从提供的 URL 下载 **X.509 证书**。例如：

   ```
   curl -s "$SIGNING_CERT_URL" -o signing_cert.pem
   ```

1. 从下载的 X.509 证书上提取**公有密钥**。您可以使用公有密钥解密消息的签名并验证其完整性。例如：

   ```
   openssl x509 -pubkey -noout -in signing_cert.pem > public_key.pem
   ```

1. 不同的消息类型需要在待签名字符串中使用不同的键值对。确定**消息类型**（Amazon SNS 消息中的 `Type` 字段）以确定要包含哪些**键值对**：
   + **通知消息**：包括 `Message`、`MessageId`、`Subject`（如果存在）`Timestamp`、`TopicArn`、和 `Type`。
   + **SubscriptionConfirmation**或**UnsubscribeConfirmation 消息**-包括`Message`、`MessageId``SubscribeURL`、`Timestamp`、`Token`、`TopicArn`、和`Type`。

1. Amazon SNS 要求待签名字符串遵循严格的固定字段顺序以进行验证。**必须仅包含明确必填的字段**，不能添加额外的字段。可选字段（例如 `Subject`）只有在消息中存在时才必须包含且必须出现在必填字段顺序所定义的确切位置。例如：

   ```
   KeyNameOne\nValueOne\nKeyNameTwo\nValueTwo
   ```
**重要**  
不要在消息结尾处添加换行符。

1. 按字节排序顺序（按键名称的字母顺序）排列**键值对**。

1. 参照以下格式示例构造**待签名字符串**：

   ```
   STRING_TO_SIGN=""
   for FIELD in "${FIELDS[@]}"; do
       VALUE=$(jq -r --arg field "$FIELD" '.[$field]' "$MESSAGE_FILE")
       STRING_TO_SIGN+="$FIELD\n$VALUE"
       # Append a newline after each field except the last one
       if [[ "$FIELD" != "Type" ]]; then
           STRING_TO_SIGN+="\n"
       fi
   done
   ```

   **通知消息示例：**

   ```
   Message
   My Test Message
   MessageId
   4d4dc071-ddbf-465d-bba8-08f81c89da64
   Subject
   My subject
   Timestamp
   2019-01-31T04:37:04.321Z
   TopicArn
   arn:aws:sns:us-east-2:123456789012:s4-MySNSTopic-1G1WEFCOXTC0P
   Type
   Notification
   ```

   **SubscriptionConfirmation 示例：**

   ```
   Message
   Please confirm your subscription
   MessageId
   3d891288-136d-417f-bc05-901c108273ee
   SubscribeURL
   https://sns.us-east-2.amazonaws.com/...
   Timestamp
   2024-01-01T00:00:00.000Z
   Token
   abc123...
   TopicArn
   arn:aws:sns:us-east-2:123456789012:MyTopic
   Type
   SubscriptionConfirmation
   ```

1. 消息中的 `Signature` 字段是经过 Base64 编码的。您需要对其进行**解码**，将其**原始二进制形式**与**派生的哈希值**进行比较。例如：

   ```
   SIGNATURE=$(jq -r '.Signature' "$MESSAGE_FILE")
   echo "$SIGNATURE" | base64 -d > signature.bin
   ```

1. 使用 `SignatureVersion` 字段选择哈希算法：
   + 对于 `SignatureVersion` **1**，使用 **SHA1**（例如，`-sha1`）。
   + 对于 `SignatureVersion` **2**，使用 **SHA256**（例如，`-sha256`）。

1. 要确认 Amazon SNS 消息的真实性，请生成构造字符串的**哈希值**，并使用**公有密钥**验证签名。

   ```
   openssl dgst -sha256 -verify public_key.pem -signature signature.bin <<< "$STRING_TO_SIGN"
   ```

   如果签名有效，则输出为 `Verified OK`。否则，输出为 `Verification Failure`。

## 带有错误处理的示例脚本
<a name="sns-verify-signature-of-message-example"></a>

以下示例脚本可自动执行验证流程：

```
#!/bin/bash

# Path to the local message file
MESSAGE_FILE="message.json"

# Extract the SigningCertURL and Signature from the message
SIGNING_CERT_URL=$(jq -r '.SigningCertURL' "$MESSAGE_FILE")
SIGNATURE=$(jq -r '.Signature' "$MESSAGE_FILE")

# Fetch the X.509 certificate
curl -s "$SIGNING_CERT_URL" -o signing_cert.pem

# Extract the public key from the certificate
openssl x509 -pubkey -noout -in signing_cert.pem > public_key.pem

# Define the fields to include in the string to sign
FIELDS=("Message" "MessageId" "Subject" "Timestamp" "TopicArn" "Type")

# Initialize the string to sign
STRING_TO_SIGN=""

# Iterate over the fields to construct the string to sign
for FIELD in "${FIELDS[@]}"; do
    VALUE=$(jq -r --arg field "$FIELD" '.[$field]' "$MESSAGE_FILE")
    STRING_TO_SIGN+="$FIELD\n$VALUE"
    # Append a newline after each field except the last one
    if [[ "$FIELD" != "Type" ]]; then
        STRING_TO_SIGN+="\n"
    fi
done

# Verify the signature
echo -e "$STRING_TO_SIGN" | openssl dgst -sha256 -verify public_key.pem -signature <(echo "$SIGNATURE" | base64 -d)
```

# 解析 Amazon SNS 消息格式
<a name="sns-message-and-json-formats"></a>

当 Amazon SNS 向 HTTP/HTTPS 终端节点发送消息时，它们同时包含 HTTP 标头和 JSON 消息正文。这些消息遵循特定的结构格式，其中包括消息类型、主题 ARN、时间戳以及数字签名等元数据。通过正确解析 Amazon SNS 消息，您可以判断消息是订阅确认、通知还是取消订阅确认，并提取相关数据，同时通过签名验证来确认消息的真实性。

# HTTP/HTTPS 标题
<a name="http-header"></a>

当 Amazon SNS 向 HTTP/HTTPS 终端节点发送订阅确认、通知或取消订阅确认消息时，它会发送一条包含许多 Amazon SNS 特定标头值的 POST 消息。可以使用标头值执行以下任务，例如识别消息类型而无需解析 JSON 消息主体来读取 `Type` 值。原定设置情况下，Amazon SNS 会将所有通知发送到 HTTP/S 端点，`Content-Type` 设置为 `text/plain; charset=UTF-8`。要选择 text/plain （默认）以`Content-Type`外的选项，请参阅`headerContentType`中的[创建配 HTTP/S 送策略](sns-message-delivery-retries.md#creating-delivery-policy)。

**`x-amz-sns-message-type`**  
消息类型。可能的值为 `SubscriptionConfirmation`、`Notification` 和 `UnsubscribeConfirmation`。

**`x-amz-sns-message-id`**  
通用唯一标识符（UUID），它对于每条发布的消息是唯一的。对于 Amazon SNS 在重试期间重新发送的通知，使用原始消息的消息 ID。

**`x-amz-sns-topic-arn`**  
此消息所发布到的主题的 Amazon 资源名称（ARN）。

**`x-amz-sns-subscription-arn`**  
用于订阅终端节点的 ARN。

下面的 HTTP POST 标头是一条发送至 HTTP 端点的 `Notification` 消息的标头示例。

```
POST / HTTP/1.1
x-amz-sns-message-type: Notification
x-amz-sns-message-id: 165545c9-2a5c-472c-8df2-7ff2be2b3b1b
x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
x-amz-sns-subscription-arn: arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55
Content-Length: 1336
Content-Type: text/plain; charset=UTF-8
Host: myhost.example.com
Connection: Keep-Alive
User-Agent: Amazon Simple Notification Service Agent
```

# HTTP/HTTPS 订阅确认 JSON 格式
<a name="http-subscription-confirmation-json"></a>

在您订阅 HTTP/HTTPS 终端节点后，Amazon SNS 会向该 HTTP/HTTPS 终端节点发送订阅确认消息。此条消息包含您必须访问的 `SubscribeURL` 值，以确认订阅（或者，您可以将 `Token` 值与 [https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html](https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html) 结合使用）。

**注意**  
直到订阅被确认后，Amazon SNS 才会向终端节点发送通知

订阅确认消息是一条 POST 消息，消息正文包含一个带以下名称/值对的 JSON 格式文档。

**`Type`**  
消息类型。为订阅确认，消息类型为：`SubscriptionConfirmation`。

**`MessageId`**  
通用唯一标识符（UUID），它对于每条发布的消息是唯一的。对于 Amazon SNS 在重试期间重新发送的消息，原始消息的消息 ID 被使用。

**`Token`**  
您可以使用 [https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html](https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html) 操作确认订阅的一个值。或者，您只需访问`SubscribeURL`。

**`TopicArn`**  
终端节点已经订阅该主题的 Amazon Resource Name。

**`Message`**  
一个描述消息的字符串。为订阅确认，字符串看上去像这样：  

```
You have chosen to subscribe to the topic arn:aws:sns:us-east-2:123456789012:MyTopic.\nTo confirm the subscription, visit the SubscribeURL included in this message.
```

**`SubscribeURL`**  
为了确认订阅而必须访问的 URL。或者，您可以改为将 `Token` 与 [https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html](https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html) 操作结合使用以确认订阅。

**`Timestamp`**  
订阅确认发出的时间 (GMT)。

**`SignatureVersion`**  
所用 Amazon SNS 签名的版本。  
+ 如果 `SignatureVersion` 为 **1**，则 `Signature` 是 `Message`、`MessageId`、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA1withRSA` 签名。
+ 如果 `SignatureVersion` 为 **2**，则 `Signature` 是 `Message`、`MessageId`、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA256withRSA` 签名。

**`Signature`**  
`Message`、`MessageId`、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA1withRSA` 或 `SHA256withRSA` 签名。

**`SigningCertURL`**  
用于签署消息的证书的 URL。

以下 HTTP POST 消息是发送至 HTTP 端点的一条 `SubscriptionConfirmation` 消息的示例。

```
POST / HTTP/1.1
x-amz-sns-message-type: SubscriptionConfirmation
x-amz-sns-message-id: 165545c9-2a5c-472c-8df2-7ff2be2b3b1b
x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
Content-Length: 1336
Content-Type: text/plain; charset=UTF-8
Host: myhost.example.com
Connection: Keep-Alive
User-Agent: Amazon Simple Notification Service Agent

{
  "Type" : "SubscriptionConfirmation",
  "MessageId" : "165545c9-2a5c-472c-8df2-7ff2be2b3b1b",
  "Token" : "2336412f37...",
  "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
  "Message" : "You have chosen to subscribe to the topic arn:aws:sns:us-west-2:123456789012:MyTopic.\nTo confirm the subscription, visit the SubscribeURL included in this message.",
  "SubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:123456789012:MyTopic&Token=2336412f37...",
  "Timestamp" : "2012-04-26T20:45:04.751Z",
  "SignatureVersion" : "1",
  "Signature" : "EXAMPLEpH+DcEwjAPg8O9mY8dReBSwksfg2S7WKQcikcNKWLQjwu6A4VbeS0QHVCkhRS7fUQvi2egU3N858fiTDN6bkkOxYDVrY0Ad8L10Hs3zH81mtnPk5uvvolIC1CXGu43obcgFxeL3khZl8IKvO61GWB6jI9b5+gLPoBc1Q=",
  "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem"
}
```

# HTTP/HTTPS 通知 JSON 格式
<a name="http-notification-json"></a>

当 Amazon SNS 向已订阅的 HTTP 或 HTTPS 终端节点发送一条通知时，发送到终端节点的 POST 消息具有包含一个带下列名称/值对的 JSON 格式文档的消息正文。

**`Type`**  
消息类型。用于通知，这种类型属于`Notification`。

**`MessageId`**  
通用唯一标识符（UUID），它对于每条发布的消息是唯一的。对于 Amazon SNS 在重试期间重新发送的通知，使用原始消息的消息 ID。

**`TopicArn`**  
此消息所发布到的主题的 Amazon 资源名称（ARN）。

**`Subject`**  
在将通知发布至主题时指定的 `Subject` 参数。  
此参数为可选参数。如果未指定 `Subject`，则此 JSON 格式文档中不会显示该名称/值对。

**`Message`**  
当通知发布至主题时指定的 `Message` 值。

**`Timestamp`**  
通知发布的时间 (GMT)。

**`SignatureVersion`**  
所用 Amazon SNS 签名的版本。  
+ 如果 `SignatureVersion` 为 **1**，则 `Signature` 是 `Message`、`MessageId`、`Subject`（如果存在）、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA1withRSA` 签名。
+ 如果 `SignatureVersion` 为 **2**，则 `Signature` 是 `Message`、`MessageId`、`Subject`（如果存在）、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA256withRSA` 签名。

**`Signature`**  
`Message`、`MessageId`、`Subject`（如果存在）、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA1withRSA` 或 `SHA256withRSA` 签名。

**`SigningCertURL`**  
用于签署消息的证书的 URL。

**`UnsubscribeURL`**  
可以用作从主题取消订阅终端节点的 URL。如果您访问此 URL，那么 Amazon SNS 将取消订阅终端节点并不发送通知至此终端节点。

以下 HTTP POST 消息是发送至 HTTP 端点的一条 `Notification` 消息的示例。

```
POST / HTTP/1.1
x-amz-sns-message-type: Notification
x-amz-sns-message-id: 22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324
x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
x-amz-sns-subscription-arn: arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96
Content-Length: 773
Content-Type: text/plain; charset=UTF-8
Host: myhost.example.com
Connection: Keep-Alive
User-Agent: Amazon Simple Notification Service Agent

{
  "Type" : "Notification",
  "MessageId" : "22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324",
  "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
  "Subject" : "My First Message",
  "Message" : "Hello world!",
  "Timestamp" : "2012-05-02T00:54:06.655Z",
  "SignatureVersion" : "1",
  "Signature" : "EXAMPLEw6JRN...",
  "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
  "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96"
  }
```

# HTTP/HTTPS 取消订阅确认 JSON 格式
<a name="http-unsubscribe-confirmation-json"></a>

在 HTTP/HTTPS 终端节点取消订阅主题后，Amazon SNS 会向该终端节点发送取消订阅确认消息。

取消订阅确认消息是一条 POST 消息，消息正文包含一个带以下名称/值对的 JSON 格式文档。

**`Type`**  
消息类型。为取消订阅确认，消息类型为`UnsubscribeConfirmation`。

**`MessageId`**  
通用唯一标识符（UUID），它对于每条发布的消息是唯一的。对于 Amazon SNS 在重试期间重新发送的消息，原始消息的消息 ID 被使用。

**`Token`**  
您可以使用 [https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html](https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html) 操作重新确认订阅的一个值。或者，您只需访问`SubscribeURL`。

**`TopicArn`**  
此终端节点已经从主题取消订阅的 Amazon Resource Name (ARN)。

**`Message`**  
一个描述消息的字符串。为了取消订阅确认，字符串应看起来像这样：  

```
You have chosen to deactivate subscription arn:aws:sns:us-east-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55.\nTo cancel this operation and restore the subscription, visit the SubscribeURL included in this message.
```

**`SubscribeURL`**  
为了重新确认订阅，您必须访问的 URL。或者，您可以改为将 `Token` 与 [https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html](https://docs.aws.amazon.com/sns/latest/api/API_ConfirmSubscription.html) 操作结合使用以重新确认订阅。

**`Timestamp`**  
取消订阅确认发送的时间(GMT)。

**`SignatureVersion`**  
所用 Amazon SNS 签名的版本。  
+ 如果 `SignatureVersion` 为 **1**，则 `Signature` 是 `Message`、`MessageId`、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA1withRSA` 签名。
+ 如果 `SignatureVersion` 为 **2**，则 `Signature` 是 `Message`、`MessageId`、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA256withRSA` 签名。

**`Signature`**  
`Message`、`MessageId`、`Type`、`Timestamp` 和 `TopicArn` 值的 Base64 编码 `SHA1withRSA` 或 `SHA256withRSA` 签名。

**`SigningCertURL`**  
用于签署消息的证书的 URL。

以下 HTTP POST 消息是发送至 HTTP 端点的一条 `UnsubscribeConfirmation` 消息的示例。

```
POST / HTTP/1.1
x-amz-sns-message-type: UnsubscribeConfirmation
x-amz-sns-message-id: 47138184-6831-46b8-8f7c-afc488602d7d
x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
x-amz-sns-subscription-arn: arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55
Content-Length: 1399
Content-Type: text/plain; charset=UTF-8
Host: myhost.example.com
Connection: Keep-Alive
User-Agent: Amazon Simple Notification Service Agent

{
  "Type" : "UnsubscribeConfirmation",
  "MessageId" : "47138184-6831-46b8-8f7c-afc488602d7d",
  "Token" : "2336412f37...",
  "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
  "Message" : "You have chosen to deactivate subscription arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55.\nTo cancel this operation and restore the subscription, visit the SubscribeURL included in this message.",
  "SubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:123456789012:MyTopic&Token=2336412f37fb6...",
  "Timestamp" : "2012-04-26T20:06:41.581Z",
  "SignatureVersion" : "1",
  "Signature" : "EXAMPLEHXgJm...",
  "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem"
}
```

# SetSubscriptionAttributes 交付策略 JSON 格式
<a name="set-sub-attributes-delivery-policy-json"></a>

如果您向 `SetSubscriptionAttributes` 操作发送一个请求并将 `AttributeName` 参数设置为 `DeliveryPolicy` 值，那么 `AttributeValue` 参数的值必须是一个有效的 JSON 对象。例如，以下例子将传输策略设置为 5 次重试。

```
http://sns.us-east-2.amazonaws.com/
?Action=SetSubscriptionAttributes
&SubscriptionArn=arn%3Aaws%3Asns%3Aus-east-2%3A123456789012%3AMy-Topic%3A80289ba6-0fd4-4079-afb4-ce8c8260f0ca
&AttributeName=DeliveryPolicy
&AttributeValue={"healthyRetryPolicy":{"numRetries":5}}
...
```

为 `AttributeValue` 参数的值使用下列 JSON 格式。

```
{
    "healthyRetryPolicy" : {
        "minDelayTarget" :  int,
        "maxDelayTarget" : int,
        "numRetries" : int,
        "numMaxDelayRetries" : int,
        "backoffFunction" : "linear|arithmetic|geometric|exponential"
    },
    "throttlePolicy" : {
        "maxReceivesPerSecond" : int
    },
    "requestPolicy" : {
        "headerContentType" : "text/plain | application/json | application/xml"
    }
}
```

有关该`SetSubscriptionAttribute`操作的更多信息，请[SetSubscriptionAttributes](https://docs.aws.amazon.com/sns/latest/api/API_SetSubscriptionAttributes.html)访问《*亚马逊简单通知服务 API 参考*》。有关支持的 HTTP content-type 标头的更多信息，请参阅[创建配 HTTP/S 送策略](sns-message-delivery-retries.md#creating-delivery-policy)。

# SetTopicAttributes 交付策略 JSON 格式
<a name="set-topic-attributes-delivery-policy-json"></a>

如果您向 `SetTopicAttributes` 操作发送一个请求并将 `AttributeName` 参数设置为 `DeliveryPolicy` 值，那么 `AttributeValue` 参数的值必须是一个有效的 JSON 对象。例如，以下例子将传输策略设置为 5 次重试。

```
http://sns.us-east-2.amazonaws.com/
?Action=SetTopicAttributes
&TopicArn=arn%3Aaws%3Asns%3Aus-east-2%3A123456789012%3AMy-Topic
&AttributeName=DeliveryPolicy
&AttributeValue={"http":{"defaultHealthyRetryPolicy":{"numRetries":5}}}
...
```

为 `AttributeValue` 参数的值使用下列 JSON 格式。

```
{
    "http" : {
        "defaultHealthyRetryPolicy" : {
            "minDelayTarget":  int,
            "maxDelayTarget": int,
            "numRetries": int,
            "numMaxDelayRetries": int,
            "backoffFunction": "linear|arithmetic|geometric|exponential"
        },
        "disableSubscriptionOverrides" : Boolean,
        "defaultThrottlePolicy" : {
            "maxReceivesPerSecond" : int
        },
        "defaultRequestPolicy" : {
            "headerContentType" : "text/plain | application/json | application/xml"
        }
    }
}
```

有关该`SetTopicAttribute`操作的更多信息，请[SetTopicAttributes](https://docs.aws.amazon.com/sns/latest/api/API_SetTopicAttributes.html)访问《*亚马逊简单通知服务 API 参考*》。有关支持的 HTTP content-type 标头的更多信息，请参阅[创建配 HTTP/S 送策略](sns-message-delivery-retries.md#creating-delivery-policy)。