使用 C# 和 AWS CDK 在 SaaS 架构中为孤岛模型进行租户登录 - AWS Prescriptive Guidance

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

使用 C# 和 AWS CDK 在 SaaS 架构中为孤岛模型进行租户登录

创建者:Tabby Ward(AWS)、Susmitha Reddy Gankidi(AWS)和 Vijai Anand Ramalingam(AWS)

代码存储库:Tennat 入职信息库

环境:PoC 或试点

技术:现代化; CloudNative;SaaS; DevOps

工作负载:开源

AWS 服务:AWS CloudFormation;亚马逊 DynamoDB;亚马逊 DynamoDB Streams;AWS Lambda;亚马逊 API Gateway

Summary

软件即服务(SaaS)应用程序可以使用各种不同的架构模型构建。孤岛模型是指向租户提供专用资源的架构。

SaaS 应用程序依靠无摩擦模型将新租户引入其环境。这通常需要编排多个组件,才能成功预调配和配置创建新租户所需所有元素。在 SaaS 架构中,此过程称为租户登录。在每个 SaaS 环境中,应通过在登录流程中使用基础设施即代码,实现登录完全自动化。

此模式将引导您完成在 Amazon Web Services(AWS)上创建租户并为租户预调配基本基础设施的示例。该模式使用 C# 和 AWS Cloud Development Kit(AWS CDK)。

因为这种模式会产生账单警报,所以我们建议在美国东部(弗吉尼亚州北部)或 us-east-1 AWS 区域 部署堆栈。有关更多信息,请参阅 AWS 文档

先决条件和限制

先决条件

限制

  • AWS CDK 使用 AWS CloudFormation,因此 AWS CDK 应用程序受 CloudFormation 服务配额的限制。有关更多信息,请参阅 AWS CloudFormation 配额。 

  • 租户 CloudFormation 堆栈是使用 CloudFormation 服务角色创建的,操作上infra-cloudformation-role带有通配符(sns* 和sqs*),但资源锁定到tenant-cluster前缀。对于生产用例,请评估此设置并仅提供对该服务角色所需访问权限。InfrastructureProvisionLambda 函数还使用通配符 (cloudformation*) 来配置 CloudFormation 堆栈,但资源锁定到前缀。tenant-cluster

  • 此示例代码的 docker 构建使用 --platform=linux/amd64 强制基于 linux/amd64 的映像。这是为了确保最终的映像构件适用于 Lambda,它默认使用 x86-64 架构。如果您需要更改目标 Lambda 架构,请务必同时更改 Dockerfiles 和 AWS CDK 代码。有关更多信息,请参阅博客文章:将 AWS Lambda 函数迁移到基于 ARM 的 AWS Graviton2 处理器

  • 堆栈删除过程不会清理堆栈生成的 CloudWatch 日志(日志组和日志)。您必须通过 AWS 管理控制台、Amazon 控制 CloudWatch 台或通过 API 手动清理日志。

此模式设置为示例。对于生产用途,请评估以下设置并根据您的业务需求进行更改:

  • 为简单起见,本示例中的 AWS Simple Storage Service(Amazon S3)存储桶未启用版本控制。根据需要评估和更新设置。

  • 为简单起见,此示例在没有身份验证、授权或节流的情况下设置 Amazon API Gateway REST API 端点。对于生产用途,我们建议将系统与业务安全基础设施集成。评估此设置并根据需要添加所需安全设置。

  • 在此租户基础设施示例中,Amazon Simple Notification Service(Amazon SNS)Amazon Simple Queue Service(Amazon SQS)仅有最低设置。根据 AWS KMS 密钥政策,每个租户的 AWS 密钥管理服务 (AWS KMS) 向账户中的亚马逊 CloudWatch和亚马逊 SN S 服务开放,供其使用。该设置只是一个占位符示例。根据您的业务用例根据需要调整设置。

  • 整个设置包括但不限于 API 终端节点以及使用 AWS 预配置和删除后端租户 CloudFormation,仅涵盖基本的成功路径案例。根据您的业务需求,使用必要的重试逻辑、额外的错误处理逻辑和安全逻辑来评估和更新设置。

  • 在撰写本文时,示例代码使用 up-to-date cdk-nag 进行测试,以检查策略。将来可能会强制执行新的策略。这些新策略可能需要您根据建议手动修改堆栈,然后才能部署堆栈。查看现有代码,确保其符合您的业务需求。

  • 该代码依赖 AWS CDK 生成随机后缀,而不是依赖静态分配的物理名称来创建大部分资源。此设置是为了确保这些资源是唯一的,并且不会与其他堆栈发生冲突。有关更多信息,请参阅 AWS CDK 文档。根据您的业务需求对此进行调整。

  • 此示例代码将 .NET Lambda 构件打包成基于 Docker 的映像,并使用 Lambda 提供的容器映像运行时系统运行。容器映像运行时系统具有的优势包括:标准传输和存储机制(容器注册表)和更精确的本地测试环境(通过容器映像)。您可以将项目切换为使用 Lambda 提供的 .NET 运行时系统来缩短 Docker 映像的构建时间,但随后您需要设置传输和存储机制,并确保本地设置与 Lambda 设置相匹配。调整代码以适应用户的业务需求。

产品版本

  • AWS CDK 版本 2.45.0 或更高版本

  • Visual Studio 2022

架构

技术堆栈

  • Amazon API Gateway

  • AWS CloudFormation

  • Amazon CloudWatch

  • Amazon DynamoDB

  • AWS Identity and Access Management (IAM)

  • AWS KMS

  • AWS Lambda

  • Amazon S3

  • Amazon SNS

  • Amazon SQS

架构

下图显示了租户堆栈的创建流程。有关控制面板和租户技术堆栈的更多信息,请参阅其他信息部分。

租户堆栈创建流程

  1. 用户向 Amazon API Gateway 托管的 REST API 发送带有 JSON 格式的新租户有效负载(租户名称、租户描述)的 POST API 请求。API 网关处理请求并将其转发到后端 Lambda 租户登录函数。在此示例中,没有授权或身份验证。在生产环境中,此 API 应与 SaaS 基础设施安全系统集成。

  2. 租户登录功能会验证请求。然后,它会尝试将租户记录(包括租户名称、生成的租户通用唯一标识符(UUID)和租户描述)存储到 Amazon DynamoDB 租户登录表中。 

  3. 在 DynamoDB 存储记录后,DynamoDB 流会启动下游 Lambda 租户基础设施函数。

  4. 租户基础设施 Lambda 函数基于收到的 DynamoDB 数据流进行操作。如果流用于 INSERT 事件,则该函数使用流的 NewImage 部分(最新更新记录,“租户名称” 字段)进行调用, CloudFormation 以使用存储在 S3 存储桶中的模板创建新的租户基础架构。 CloudFormation 模板需要租户名称参数。 

  5. AWS 根据 CloudFormation 模板和输入参数 CloudFormation 创建租户基础设施。

  6. 每个租户基础设施设置都有一个 CloudWatch 警报、一个账单警报和一个警报事件。

  7. 警报事件将变成 SNS 主题的消息,该消息由租户的 AWS KMS 密钥加密。

  8. SNS 主题将收到的警报消息转发到 SQS 队列,该队列由租户的 AWS KMS 加密以获取加密密钥。

其他系统可以与 Amazon SQS 集成,根据队列中的消息执行操作。在此示例中,为了保持代码的通用性,传入的消息将保留在队列中,需要手动删除。

租户堆栈删除流程

  1. 用户向 Amazon API Gateway 托管的 REST API 发送带有 JSON 格式的新租户有效负载(租户名称、租户描述)的 DELETE API 请求,REST API 将处理该请求并转发到租户登录功能。在此示例中,没有授权或身份验证。在生产环境中,此 API 将与 SaaS 基础设施安全系统集成。

  2. 租户登录功能将验证请求,然后尝试从租户登录表中删除租户记录(租户名称)。 

  3. DynamoDB 成功删除记录(该记录存在于表中并已删除)后,DynamoDB 流将启动下游 Lambda 租户基础设施函数。

  4. 租户基础设施 Lambda 函数基于收到的 DynamoDB 数据流记录进行操作。如果流是针对REMOVE事件,则该函数使用记录的 OldImage 部分(记录信息和租户名称字段,位于最新更改之前,即删除),根据该记录信息启动对现有堆栈的删除。

  5. AWS 根据输入 CloudFormation 删除目标租户堆栈。

工具

Amazon Web Services

  • Amazon API Gateway 可帮助您创建、发布、维护、监控和保护任何规模的 REST、HTTP 和 WebSocket API。

  • AWS Cloud Development Kit (AWS CDK) 是一个软件开发框架,可帮助您在代码中定义和预调配 Amazon Web Services Cloud 基础设施。

  • AWS CDK Toolkit 是命令行云开发套件,可帮助您与 AWS Cloud Development Kit(AWS CDK)应用程序进行交互。

  • AWS 命令行界面(AWS CLI)是一种开源工具,它可帮助您通过命令行 Shell 中的命令与 Amazon Web Services 交互。

  • AWS CloudFormation 可帮助您设置 AWS 资源,快速一致地配置这些资源,并在 AWS 账户和区域的整个生命周期中对其进行管理。

  • Amazon DynamoDB 是一项完全托管的 NoSQL 数据库服务,可提供快速、可预测和可扩展的性能。

  • AWS Identity and Access Management (AWS IAM) 通过控制验证和授权使用您 AWS 资源的用户,帮助您安全地管理对您 AWS 资源的访问。

  • AWS Key Management Service (AWS KMS) 可帮助您创建和控制加密密钥,以帮助保护您的数据。

  • AWS Lambda 是一项计算服务,可帮助您运行代码,而无需预置或管理服务器。它仅在需要时运行您的代码,并且能自动扩缩,因此您只需为使用的计算时间付费。

  • Amazon Simple Storage Service (Amazon S3)是一项基于云的对象存储服务,可帮助您存储、保护和检索任意数量的数据。

  • Amazon Simple Notification Service (Amazon SNS) 可帮助您协调和管理发布者与客户端(包括 Web 服务器和电子邮件地址)之间的消息交换。

  • Amazon Simple Queue Service (Amazon SQS) 提供了一个安全、持久且可用的托管队列,它可帮助您集成和分离分布式软件系统与组件。

  • AWS Toolkit for Visual Studio 是 Visual Studio 集成式开发环境(IDE)的插件。Toolkit for Visual Studio 支持开发、调试和部署使用 Amazon Web Services 的 .NET 应用程序。

其他工具

  • Visual Studio 是一个 IDE,包括编译器、代码完成工具、图形设计器和其他支持软件开发的功能。

代码

此模式的代码位于孤岛模型的 SaaS 架构中的租户登录 APG 示例存储库中。

操作说明

任务描述所需技能

验证 Node.js 的安装。

要验证 Node.js 是否已安装在本地计算机上,请运行以下命令。

node --version
AWS 管理员,AWS DevOps

安装 AWS CDK Toolkit。

要在本地计算机上安装 AWS CDK Toolkit,请运行以下命令。

npm install -g aws-cdk

如果未安装 npm,则可以从 Node.js 站点进行安装。

AWS 管理员,AWS DevOps

验证 AWS CDK Toolkit 的版本。

要验证 AWS CDK Toolkit 版本是否已在本机上正确安装,请运行以下命令。 

cdk --version
AWS 管理员,AWS DevOps
任务描述所需技能

克隆存储库。

克隆存储库,然后导航到该 \tenant-onboarding-in-saas-architecture-for-silo-model-apg-example 文件夹。

在 Visual Studio 2022 中,打开 \src\TenantOnboardingInfra.sln 解决方案。打开 TenantOnboardingInfraStack.cs 文件并查看代码。

以下资源是作为此堆栈的一部分创建的:

  • DynamoDB 表

  • S3 存储桶(将 CloudFormation 模板上传到 S3 存储桶。)

  • Lambda 执行角色

  • Lambda 函数

  • API 网关 CLI

  • Lambda 函数的事件源

AWS 管理员,AWS DevOps

查看 CloudFormation 模板。

\tenant-onboarding-in-saas-architecture-for-silo-model-apg-example\template文件夹中infra.yaml,打开并查看 CloudFormation 模板。此模板将使用从租户登录 DynamoDB 表中检索到的租户名称注入数据。

该模板提供了租户特定的基础设施。在此示例中,它配置了 AWS KMS 密钥、亚马逊 SNS、亚马逊 SQS 和警报。 CloudWatch

AWS 应用程序开发人员 DevOps

查看租户登录函数。

打开 Function.cs 并查看租户登录函数的代码,该代码是使用带有 .NET 6(容器映像)蓝图的 Visual Studio AWS Lambda 项目 (.NET Core- C#) 模板创建的。

打开 Dockerfile并查看代码。Dockerfile 是一个文本文件,包含构建 Lambda 容器映像的说明。

请注意,以下 NuGet 包已作为依赖项添加到TenantOnboardingFunction项目中:

  • Amazon.Lambda.APIGatewayEvents

  • AWSSDK.DynamoDBv2

  • Newtonsoft.Json

AWS 应用程序开发人员 DevOps

查看租户 InfraProvisioning 功能。

导航到 \tenant-onboarding-in-saas-architecture-for-silo-model-apg-example\src\InfraProvisioningFunction

打开 Function.cs 并查看租户基础设施预调配函数的代码,该代码是使用带有 .NET 6(容器映像)蓝图的 Visual Studio AWS Lambda 项目(.NET Core-C#)模板创建的。

打开 Dockerfile 并查看代码。

请注意,以下 NuGet 包已作为依赖项添加到InfraProvisioningFunction项目中:

  • Amazon.Lambda.DynamoDBEvents

  • AWSSDK.DynamoDBv2

  • AWSSDK.Cloudformation

AWS 应用程序开发人员 DevOps
任务描述所需技能

构建解决方案。

要构建解决方案,请执行以下步骤:

  1. 在 Visual Studio 2022 中,打开 \tenant-onboarding-in-saas-architecture-for-silo-model-apg-example\src\TenantOnboardingInfra.sln 解决方案。 

  2. 打开解决方案的上下文(右键单击)菜单,然后选择构建解决方案

注意:在构建解决方案之前,请务必将 Amazon.CDK.Lib NuGet 软件包更新到 \tenant-onboarding-in-saas-architecture-for-silo-model-apg-example\src\TenantOnboardingInfra 项目中的最新版本。

应用程序开发人员

引导 AWS CDK 环境。

打开 Windows 命令提示符并导航到 cdk.json 文件所在的 AWS CDK 应用程序根文件夹(\tenant-onboarding-in-saas-architecture-for-silo-model-apg-example)。运行以下命令进行引导。

cdk bootstrap

如果您已为凭证创建了 AWS 配置文件,请将命令与配置文件一起使用。

cdk bootstrap --profile <profile name>
AWS 管理员,AWS DevOps

列出 AWS CDK 堆栈。

要列出要作为本项目的一部分创建的所有堆栈,请运行以下命令。

cdk ls cdk ls --profile <profile name>

如果您已为凭证创建了 AWS 配置文件,请将命令与配置文件一起使用。

cdk ls --profile <profile name>
AWS 管理员,AWS DevOps

查看将创建哪些 AWS 资源。

要查看将作为此项目的一部分创建的所有 AWS 资源,请运行以下命令。

cdk diff

如果您已为凭证创建了 AWS 配置文件,请将命令与配置文件一起使用。

cdk diff --profile <profile name>
AWS 管理员,AWS DevOps

使用 AWS CDK 部署所有 AWS 资源。

要部署所有 AWS 资源,请运行以下命令。

cdk deploy --all --require-approval never

如果您已为凭证创建了 AWS 配置文件,请将命令与配置文件一起使用。

cdk deploy --all --require-approval never --profile <profile name>

部署完成后,从命令提示符的输出部分复制 API URL,如以下示例所示。

Outputs: TenantOnboardingInfraStack.TenantOnboardingAPIEndpoint42E526D7 = https://j2qmp8ds21i1i.execute-api.us-west-2.amazonaws.com/prod/
AWS 管理员,AWS DevOps
任务描述所需技能

创建新租户。

要创建新租户,请发送以下 curl 请求。

curl -X POST <TenantOnboardingAPIEndpoint* from CDK Output>tenant -d '{"Name":"Tenant123", "Description":"Stack for Tenant123"}'

将占位符 <TenantOnboardingAPIEndpoint* from CDK Output> 更改为 AWS CDK 中的实际值,如以下示例所示。

curl -X POST https://j2qmp8ds21i1i.execute-api.us-west-2.amazonaws.com/prod/tenant -d '{"Name":"Tenant123", "Description":"test12"}'

以下示例显示了输出。

{"message": "A new tenant added - 5/4/2022 7:11:30 AM"}
应用程序开发人员、AWS 管理员、AWS DevOps

在 DynamoDB 中验证新创建租户的详细信息。

要验证 DynamoDB 中新创建租户的详细信息,请执行以下步骤。

  1. 打开 AWS 管理控制台,然后导航到 Amazon DynamoDB 服务。

  2. 在左侧导航栏中,选择探索项目,然后选择 TenantOnboarding 表格。

    注意:租户名称前面将加上 tenantcluster-。有关更多信息,请参阅其他信息部分。

  3. 验证是否使用租户详细信息创建了一个新项目。

应用程序开发人员、AWS 管理员、AWS DevOps

验证为新租户创建的堆栈。

验证新堆栈是否已成功创建并根据 CloudFormation 模板为新创建的租户配置了基础架构。

  1. 打开控制 CloudFormation 台。

  2. 在左侧导航栏中,选择堆栈,然后验证是否已成功创建具有租户名称的堆栈。

  3. 选择新创建租户的堆栈,然后选择资源选项卡。记下警报资源和 Amazon SQS 资源。

  4. 打开配置了 AWS 凭证的新终端,然后指向正确的区域。要发出测试警报,请输入以下代码,<alarm resource name> 替换为步骤 3 中注明的警报资源名称。

    aws cloudwatch set-alarm-state --alarm-name <alarm resource name> --state-value ALARM --state-reason 'Test setup'

    以下示例显示了带有警报资源名称的代码。

    aws cloudwatch set-alarm-state --alarm-name tenantcluster-tenant123-alarm --state-value ALARM --state-reason 'Test setup'
  5. 打开控制台,然后导航到 Amazon SQS 控制台。选择步骤 3 中标识的 Amazon SQS 资源名称。按照 AWS 文档说明接收和删除步骤 4 中发出的警报中的测试消息。

应用程序开发人员、AWS 管理员、AWS DevOps

删除租户堆栈。

要删除租户堆栈,请发送以下 curl 请求。

curl -X DELETE <TenantOnboardingAPIEndpoint* from CDK Output>tenant/<Tenant Name from previous step>

将占位符 <TenantOnboardingAPIEndpoint* from CDK Output> 更改为 AWS CDK 中的实际值,然后更改 <Tenant Name from previous step> 为上一个租户创建步骤中的实际值,如以下示例所示。

curl -X DELETE https://j2qmp8ds21i1i.execute-api.us-west-2.amazonaws.com/prod/tenant/Tenant123

以下示例显示了输出。

{"message": "Tenant destroyed - 5/4/2022 7:14:48 AM"}
应用程序开发人员、AWS DevOps、AWS 管理员

验证现有租户的堆栈删除。

要验证现有租户的堆栈是否已删除,请执行以下步骤:

  1. 打开控制台并导航到 CloudFormation 控制台。

  2. 在左侧导航栏中,确认带有租户名称的现有堆栈已不在 CloudFormation 控制台中(如果控制台设置为仅显示活动堆栈)或正在被删除。如果堆栈已不在 CloudFormation 控制台中,请使用下拉列表将控制台的设置从 “活动” 更改为 “已删除”,以查看已删除的堆栈并验证堆栈是否已成功删除。

应用程序开发人员、AWS 管理员、AWS DevOps
任务描述所需技能

摧毁环境。

在清理堆栈之前,请确保满足以下条件:

  • DynamoDB 中的所有记录均通过之前的租户删除操作或通过 DynamoDB 控制台或 API 删除。每次删除租户记录都将启动清理其 AWS CloudFormation 对应记录。 

  • 在 AWS 控制台上清理所有基于租户的 AWS CloudFormation 堆栈(以防万一 DynamoDB 触发器清理逻辑失败)。 CloudFormation

测试完成后,可以通过运行以下命令使用 AWS CDK 销毁所有堆栈和相关资源。

cdk destroy --all;

如果您已为凭证创建了 AWS 配置文件,请使用配置文件。

确认堆栈删除提示以删除堆栈。

AWS 管理员,AWS DevOps

清理 Amazon CloudWatch 日志。

堆栈删除过程不会清理堆栈生成的日 CloudWatch 志(日志组和日志)。使用 CloudWatch 控制台或 API 手动清理 CloudWatch 资源。

应用程序开发人员、AWS DevOps、AWS 管理员

相关资源

其他信息

控制面板技术堆栈

用 .NET 编写的 CDK 代码用于预调配控制面板基础设施,该基础设施由以下资源组成:

  1. API Gateway

    用作控制面板堆栈的 REST API 入口点。

  2. 租户登录 Lambda 函数

    此 Lambda 函数由 API 网关使用 m 方法启动。

    POST 方法 API 请求会导致(tenant nametenant description)被插入到 DynamoDB 表 Tenant Onboarding 中。

    在此代码示例中,租户名称也用作租户堆栈名称的一部分以及该堆栈中资源的名称。这是为了使这些资源更易于识别。此租户名称在设置中必须是唯一的,以避免冲突或错误。详细的输入验证设置在 IAM 角色文档和限制部分中进行了说明。

    只有在表中的任何其他记录中未使用租户名称时,DynamoDB 表的持久化过程才会成功。

    在这种情况下,租户名称是该表的分区键,因为只有分区键可以用作 PutItem 条件表达式。

    如果以前从未记录过租户名称,则该记录将成功保存到表格中。

    但是,如果表中的现有记录已使用租户名称,则操作将失败并启动 DynamoDB ConditionalCheckFailedException 异常。该异常将用于返回一条失败消息(HTTP BadRequest),指示租户名称已存在。

    DELETE 方 法 API 请求将从 Tenant Onboarding 表中删除特定租户名称的记录。

    即使该记录不存在,本示例中的 DynamoDB 记录删除也会成功。

    如果目标记录存在并被删除,它将创建一个 DynamoDB 数据流记录。否则,将不会创建任何下游记录。

  3. 在 Amazon DynamoDB Streams 启用时的租户登录 DynamoDB

    这会记录租户元数据信息,任何记录的保存或删除都会将数据流发送到下游 Tenant InfrastructureLambda 函数。 

  4. 租户基础设施 Lambda 函数

    此 Lambda 函数由上一步中的 DynamoDB 数据流记录启动。如果记录是针对某个INSERT事件的,则它会调用 AWS CloudFormation 以使用存储在 S3 存储桶中的 CloudFormation 模板创建新的租户基础设施。如果该记录用于 REMOVE,则它会根据流记录的 Tenant Name 字段启动对现有堆栈的删除。

  5. S3 bucket

    这是用来存储 CloudFormation 模板的。

  6. 每个 Lambda 函数的 IAM 角色和一个服务角色 CloudFormation

    每个 Lambda 函数都有其唯一的 IAM 角色,该角色具有完成任务的最低权限许可。例如,Tenant On-boarding Lambda 函数具有对 DynamoDB 的读/写访问权限,而 Tenant Infrastructure Lambda 函数对 DynamoDB 流只有读取权限。

    为租户堆栈置备创建了自定义 CloudFormation 服务角色。此服务角色包含 CloudFormation 堆栈配置的其他权限(例如,AWS KMS 密钥)。这会在 Lambda 之间划分角色 CloudFormation ,以避免对单个角色(基础设施 Lambda 角色)拥有所有权限。

    允许强大操作(例如创建和删除 CloudFormation 堆栈)的权限被锁定,并且仅允许在以开头的资源上使用tenantcluster-。AWS KMS 是个例外,因为它的资源命名约定。从 API 摄取的租户名称将与其他验证检查一起添加到 tenantcluster- 前面(仅带破折号的字母数字,并且限制在 30 个字符以内,以适应大多数 AWS 资源命名)。这样可以确保租户名称不会意外导致核心基础设施堆栈或资源中断。

租户技术堆栈

CloudFormation 模板存储在 S3 存储桶中。该模板预置了租户特定的 AWS KMS 密钥、 CloudWatch 警报、SNS 主题、SQS 队列和 SQS 策略。

AWS KMS 密钥用于其消息的 Amazon SNS 和 Amazon SQS 的数据加密。-SNS AwsSolutions2 和 AwsSolutions-SQS2 的安全实践建议您设置带加密功能的 Amazon S NS 和亚马逊 SQS。但是,使用 AWS 托管密钥时, CloudWatch 警报不适用于 Amazon SNS,因此在这种情况下,您必须使用客户托管密钥。有关更多信息,请参阅 AWS Knowledge Center

在 Amazon SQS 队列上使用 SQS 策略来允许创建的 SNS 主题将消息传送到队列。如果没有 SQS 策略,访问将被拒绝。有关更多信息,请参阅 Amazon SNS 文档