

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

# 将 Amazon SNS 消息发送到不同账户中的 Amazon SQS 队列
<a name="sns-send-message-to-sqs-cross-account"></a>

本文档介绍如何通过另一个账户中的一个或多个 Amazon SQS 队列订阅将通知发布到 Amazon SNS 主题。如果主题和队列在同一账户下，那么您可以采用相同方法设置主题和队列（参阅 [将 Amazon SNS 通知扇出到 Amazon SQS 队列进行异步处理](sns-sqs-as-subscriber.md)）。主要区别在于您处理订阅确认的方式，这取决于您如何为队列订阅主题。

最佳做法是尽可能遵循[队列拥有者创建订阅](#SendMessageToSQS.cross.account.queueowner)部分中引用的步骤，因为当队列拥有者创建订阅时会自动进行确认。

**注意**  
如果 Amazon SQS 队列有大量消息，建议队列所有者创建订阅。

## 队列拥有者创建订阅
<a name="SendMessageToSQS.cross.account.queueowner"></a>

创建 Amazon SQS 队列的账户是队列拥有者。如果订阅由队列所有者创建，那么此订阅无需确认。一旦 `Subscribe` 操作完成后，队列即开始接收来自主题的通知。主题所有者必须提供队列所有者的账户权限，允许其对主题调用 `Subscribe` 操作，从而让队列所有者订阅主题所有者的主题。

### 步骤 1：使用设置主题策略 Amazon Web Services 管理控制台
<a name="sns-tutorial-set-topic-policy"></a>

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

1. 在导航面板上，选择**主题**。

1. 选择一个主题，然后选择 **Edit**（编辑）。

1. 在 **“编辑” *MyTopic*** 页面上，展开 “**访问策略**” 部分。

1. 输入以下策略：

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

   此策略授予账户 `111122223333` 对账户 `123456789012` 中的 `MyTopic` 调用 `sns:Subscribe` 的权限。

   具有账户 `111122223333` 的凭证的用户可以订阅 `MyTopic`。此权限允许账户 ID 将权限委派给其 IAM 用户/角色。只有根账户或管理员用户才可以调用 `sns:Subscribe`。IAM 还 user/role 必须`sns:subscribe`允许其队列进行订阅。

1. 选择**保存更改**。

   拥有账户凭证的用户`111122223333`可以订阅 MyTopic。

### 第 2 步：要将 Amazon SQS 队列订阅添加到另一个 Amazon Web Services 账户 主题中的某个主题，请使用 Amazon Web Services 管理控制台
<a name="sns-tutorial-add-sqs-subscription-to-sns-topic-another-account"></a>

在开始之前，请确保您拥有主题和队列 ARNs 的[权限，并且您已向该主题授予向队列发送消息的](subscribe-sqs-queue-to-sns-topic.md#SendMessageToSQS.sqs.permissions)权限。

1. 登录 [Amazon SQS 控制台](https://console.amazonaws.cn/sqs/home)。

1. 在导航窗格中，选择 **Queues**（队列）。

1.  从队列列表中，选择 **queue**（排队）以订阅 Amazon SNS 主题。

1. 选择 **Subscribe to Amazon SNS topic**（订阅 Amazon SNS 主题）。

1. 从 **Specify an Amazon SNS topic available for this queue menu**（指定可用于此队列菜单的 Amazon SNS 主题）中，选择队列的 **Amazon SNS topic**（Amazon SNS 主题）。

1. 选择 **Enter Amazon SNS topic ARN**（输入 Amazon SNS 主题 ARN），然后输入主题的 **Amazon Resource Name (ARN)**。

1. 选择**保存**。
**注意**  
要能够与服务通信，队列必须具有 Amazon SNS 的权限。
由于您是队列的所有者，因此您无需确认订阅。

## 非队列所有者用户创建订阅
<a name="SendMessageToSQS.cross.account.notqueueowner"></a>

创建订阅但不是队列所有者的任何用户都必须确认订阅。

使用 `Subscribe` 操作时，Amazon SNS 向队列发送订阅确认。订阅将显示在 Amazon SNS 控制台中，其订阅 ID 设置为**等待确认**。

要确认订阅，具有从队列中读取消息的权限的用户必须检索订阅确认 URL，而且订阅拥有者必须使用订阅确认 URL 以确认订阅。确认订阅前，向主题发布的通知不会发送至队列。要确认订阅，您可以使用 Amazon SQS 控制台或 `[ReceiveMessage](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/APIReference/Query_QueryReceiveMessage.html)` 操作。

**注意**  
在为终端节点订阅主题之前，请通过为队列设置 `sqs:SendMessage` 权限来确保队列可以接收来自主题的消息。有关更多信息，请参阅 [步骤 2. 为向 Amazon SQS 队列发送消息的 Amazon SNS 主题授予权限](subscribe-sqs-queue-to-sns-topic.md#SendMessageToSQS.sqs.permissions)。

### 步骤 1：要将 Amazon SQS 队列订阅添加到另一个 Amazon Web Services 账户 主题中的某个主题，请使用 Amazon Web Services 管理控制台
<a name="sns-tutorial-add-sqs-subscription-to-sns-topic-another-account"></a>

在开始之前，请确保您拥有主题和队列 ARNs 的[权限，并且您已向该主题授予向队列发送消息的](subscribe-sqs-queue-to-sns-topic.md#SendMessageToSQS.sqs.permissions)权限。

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

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

1. 在**订阅**页面上，选择**创建订阅**。

1.  在**创建订阅**页上的**详细信息**部分，执行以下操作：

   1. 对于 **Topic ARN (主题 ARN)**，输入主题的 ARN。

   1. 对于 **Protocol**（协议），选择 **Amazon SQS**。

   1. 对于 **Endpoint**（终端节点），输入队列的 ARN。

   1. 选择 **Create subscription**（创建订阅）。
**注意**  
要能够与服务通信，队列必须具有 Amazon SNS 的权限。

下面是允许 Amazon SNS 主题向 Amazon SQS 队列发送消息的示例策略声明。

```
{
   "Sid": "Stmt1234",
   "Effect": "Allow",
   "Principal": "*",
   "Action": "sqs:SendMessage",
   "Resource": "arn:aws:sqs:us-west-2:111111111111:QueueName",
   "Condition": {
      "ArnEquals": {
         "aws:SourceArn": "arn:aws:sns:us-west-2:555555555555:TopicName"
      }
   }
}
```

### 第 2 步：使用确认订阅 Amazon Web Services 管理控制台
<a name="sns-tutorial-confirm-subscription-console"></a>

1. 登录 [Amazon SQS 控制台](https://console.amazonaws.cn/sqs/)。

1. 选择主题处于等待订阅阶段的队列。

1. 选择 **Send and receive messages**（发送和接收消息），然后选择 **Poll for messages**（轮询消息）。

   队列中会收到一条带有订阅确认的消息。

1. 在 **Body**（正文）列中，执行以下操作：

   1. 选择 **More Details**（更多详情）。

   1. 在 **Message Details**（消息详细信息）对话框中，找到并记下 **SubscribeURL** 值。这是您的订阅链接（下面的示例）。有关 API 令牌验证的更多详细信息，请参阅《Amazon SNS API 参考》中的 [https://docs.amazonaws.cn/sns/latest/api/API_ConfirmSubscription.html](https://docs.amazonaws.cn/sns/latest/api/API_ConfirmSubscription.html)。

      ```
      https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-east-2:123456789012:MyTopic&Token=2336412f37fb...
      ```

   1. 记下订阅确认链接。必须将 URL 从队列拥有者传递给订阅拥有者。订阅拥有者必须在 [Amazon SNS 控制台](https://console.amazonaws.cn/sns/v3/home)中输入此 URL。

1. 以**订阅拥有者** 身份登录 [Amazon SNS 控制台](https://console.amazonaws.cn/sns/v3/home)。订阅拥有者执行确认。

1. 选择相关**主题**。

1. 在主题的订阅清单表格中选择相关**订阅**。它被标记为“Pending confirmation”（等待确认）。

1. 选择 **Confirm subscription**（确认订阅）。

1. 将出现一个提示订阅确认链接的模态框。**粘贴** 订阅确认链接。

1. 在模态框中选择 **Confirm subscription**（确认订阅）。

   将显示 XML 响应，例如：

   ```
   <ConfirmSubscriptionResponse>
      <ConfirmSubscriptionResult>
         <SubscriptionArn>arn:aws:sns:us-east-2:123456789012:MyTopic:1234a567-bc89-012d-3e45-6fg7h890123i</SubscriptionArn>
      </ConfirmSubscriptionResult>
      <ResponseMetadata>
         <RequestId>abcd1efg-23hi-jkl4-m5no-p67q8rstuvw9</RequestId>
      </ResponseMetadata>
   </ConfirmSubscriptionResponse>
   ```

   已订阅队列已准备好接收来自主题的消息。

1. （可选）如果您在 Amazon SNS 控制台中查看主题订阅，则可以看到**等待确认**消息已被 **Subscription ID**（订阅 ID）列中的订阅 ARN 取代。

## 如何强制订阅要求对取消订阅请求进行身份验证？
<a name="sns-send-message-to-sqs-cross-account-AuthenticateOnUnsubscribe"></a>

订阅拥有者必须在订阅确认后将 `AuthenticateOnUnsubscribe` 标志设置为 true。
+ 如果订阅由队列拥有者创建，则 `AuthenticateOnUnsubscribe` 自动设置为 true。
+ 在没有身份验证的情况下导航到订阅确认链接时，无法将 `AuthenticateOnUnsubscribe` 设置为 true。