用于 Amazon SNS 访问控制的示例案例 - Amazon Simple Notification Service

用于 Amazon SNS 访问控制的示例案例

本节描述了针对访问控制的几个典型使用案例示例。

授予对主题的 AWS 账户 访问权限

假设您在 Amazon SNS 中有一个主题,并且您想允许一个或多个 AWS 账户对该主题执行特定操作,例如发布消息。使用 Amazon SNS API 操作 AddPermission 即可做到这一点。

AddPermission 操作允许您指定主题、AWS 账户 ID 列表、操作列表和标签。然后,Amazon SNS 会自动生成新的策略声明,并将其添加到该主题的访问控制策略中。您无需自己编写策略声明,Amazon SNS 将为您处理。如果您以后需要移除该策略,则可以通过调用 RemovePermission 并提供您在添加权限时使用的标签来实现。

例如,如果您对主题 arn:aws:sns:us-east-2:444455556666:MyTopic 调用 AddPermission,指定 AWS 账户 ID 1111-2222-3333、Publish 操作及标签 grant-1234-publish,那么 Amazon SNS 会生成以下策略声明并将其插入到该主题的访问控制策略中:

{ "Statement": [{ "Sid": "grant-1234-publish", "Effect": "Allow", "Principal": { "AWS": "111122223333" }, "Action": ["sns:Publish"], "Resource": "arn:aws:sns:us-east-2:444455556666:MyTopic" }] }

添加此声明之后,AWS 账户 1111-2222-3333 将获得向该主题发布消息的权限。

其他信息:

  • 自定义策略管理:虽然 AddPermission 可以方便地授予权限,但对于更复杂的场景,例如添加条件或向特定 IAM 角色或服务授予权限,手动管理主题的访问控制策略通常很有用。为此,您可以使用 SetTopicAttributes API 直接更新策略属性。

  • 安全最佳实践:在授予权限时要谨慎行事,确保只有受信任的 AWS 账户或实体才能访问您的 Amazon SNS 主题。定期审查和审核您的主题所附的策略,以维护安全性。

  • 策略限制:请记住,Amazon SNS 策略的规模和复杂性有限制。如果您需要添加许多权限或复杂条件,请确保您的策略保持在这些限制范围内。

限制 HTTPS 订阅

要将您的 Amazon SNS 主题的通知传送协议限制为 HTTPS,您必须创建自定义策略。Amazon SNS 中的 AddPermission 操作不允许您在授予主题访问权限时指定协议限制。因此,您需要手动编写强制执行此限制的策略,然后使用 SetTopicAttributes 操作将该策略应用于您的主题。

您可以通过以下方式创建限制订阅 HTTPS 的策略:

  1. 撰写策略。该策略必须指定您要授予访问权限的 AWS 账户 ID,并强制执行仅允许 HTTPS 订阅的条件。以下是一个策略示例,该策略授予 AWS 账户 ID 1111-2222-3333 订阅该主题的权限,但前提是使用的协议是 HTTPS。

    { "Statement": [{ "Sid": "Statement1", "Effect": "Allow", "Principal": { "AWS": "111122223333" }, "Action": ["sns:Subscribe"], "Resource": "arn:aws:sns:us-east-2:444455556666:MyTopic", "Condition": { "StringEquals": { "sns:Protocol": "https" } } }] }
  2. 应用策略。使用 Amazon SNS API 中的 SetTopicAttributes 操作将此策略应用于您的主题。将主题的 Policy 属性设置为您创建的 JSON 策略。

    snsClient.setTopicAttributes(SetTopicAttributesRequest.builder() .topicArn("arn:aws:sns:us-east-2:444455556666:MyTopic") .attributeName("Policy") .attributeValue(jsonPolicyString) // The JSON policy as a string .build());

其他信息:

  • 自定义访问控制。这种方法允许您实施更精细的访问控制,例如限制订阅协议,而光靠 AddPermission 操作是无法实现的。自定义策略为需要特定条件(例如协议强制执行或 IP 地址限制)的场景提供了灵活性。

  • 安全最佳实践。将订阅限制为 HTTPS 可确保传输中的数据经过加密,从而增强通知的安全性。定期查看您的主题策略,确保它们符合您的安全和合规性要求。

  • 策略测试。在生产环境中应用策略之前,请在开发环境中对其进行测试,以确保其行为符合预期。这有助于防止意外访问问题或意外限制。

发布消息到 Amazon SQS 队列

要将来自您的 Amazon SNS 主题的消息发布到 Amazon SQS 队列,您需要在 Amazon SQS 队列上配置正确的权限。虽然 Amazon SNS 和 Amazon SQS 都使用 AWS 的访问控制策略语言,但您必须在 Amazon SQS 队列上明确设置策略,以允许从 Amazon SNS 主题发送消息。

您可以使用 SetQueueAttributes 操作将自定义策略应用于 Amazon SQS 队列,从而实现此目的。与 Amazon SNS 不同,Amazon SQS 不支持创建带有条件的策略声明的 AddPermission 操作。因此,您必须手动编写策略。

以下是 Amazon SQS 策略的示例,该策略授予对 Amazon SNS 向队列发送消息的权限。请注意,此策略与 Amazon SQS 队列有关,与 Amazon SNS 主题无关。这些指定操作都是 Amazon SQS 操作,并且资源是队列的 Amazon 资源名称(ARN)。您可以使用 GetQueueAttributes 操作检索队列的 ARN。

{ "Statement": [{ "Sid": "Allow-SNS-SendMessage", "Effect": "Allow", "Principal": { "Service": "sns.amazonaws.com" }, "Action": ["sqs:SendMessage"], "Resource": "arn:aws:sqs:us-east-2:444455556666:MyQueue", "Condition": { "ArnEquals": { "aws:SourceArn": "arn:aws:sns:us-east-2:444455556666:MyTopic" } } }] }

这种策略,根据所发送信息的来源,利用 aws:SourceArn 条件限制对 SQS 队列的访问。这样可确保只允许将来自指定 SNS 主题(在本例中是 arn:aws:sns:us-east-2:444455556666:MyTopic)的消息传送到队列。

其他信息:

  • 队列 ARN。确保您使用 GetQueueAttributes 操作检索 Amazon SQS 队列的正确 ARN。此 ARN 对于设置正确的权限至关重要。

  • 安全最佳实践。设置策略时,请始终遵循最低权限原则。仅向 Amazon SNS 主题授予与 Amazon SQS 队列交互的必要权限,并定期查看您的策略,确保它们是最新且安全的

  • Amazon SNS 中的默认策略。与某些误解相反,Amazon SNS 不会自动授予允许其他 AWS 服务 访问新创建主题的默认策略。您必须明确定义并附加策略来控制对 Amazon SNS 主题的访问权限。

  • 测试和验证。设置策略后,通过将消息发布到 Amazon SNS 主题并验证消息是否已成功传送到 Amazon SQS 队列来测试集成。这有助于确认策略配置是否正确。

允许 Amazon S3 事件通知发布到主题

要允许另一个 AWS 账户的 Amazon S3 存储桶向您的 Amazon SNS 主题发布事件通知,您需要相应地配置该主题的访问策略。这包括编写自定义策略,向特定 AWS 账户的 Amazon S3 服务授予权限,然后将此策略应用于您的 Amazon SNS 主题。

您可以通过以下方式进行设置:

  1. 撰写策略。该策略应授予 Amazon S3 服务(s3.amazonaws.com)发布到 Amazon SNS 主题所需的权限。您将使用 SourceAccount 条件来确保只有拥有 Amazon S3 存储桶的指定 AWS 账户才能向您的主题发布通知。

    下面是一个策略示例:

    { "Statement": [{ "Effect": "Allow", "Principal": { "Service": "s3.amazonaws.com" }, "Action": "sns:Publish", "Resource": "arn:aws:sns:us-east-2:111122223333:MyTopic", "Condition": { "StringEquals": { "AWS:SourceAccount": "444455556666" } } }] }
    • 主题所有者 – 111122223333 是拥有 Amazon SNS 主题的 AWS 账户 ID。

    • Amazon S3 存储桶所有者 - 444455556666 是拥有发送通知的 Amazon S3 存储桶的 AWS 账户 ID。

  2. 应用策略。使用 SetTopicAttributes 操作在您的 Amazon SNS 主题上设置此策略。这将更新主题的访问控制,使其包含您的自定义策略中指定的权限。

    snsClient.setTopicAttributes(SetTopicAttributesRequest.builder() .topicArn("arn:aws:sns:us-east-2:111122223333:MyTopic") .attributeName("Policy") .attributeValue(jsonPolicyString) // The JSON policy as a string .build());

其他信息:

  • 使用 SourceAccount 条件。SourceAccount 条件可确保只有源自指定 AWS 账户(在本例中为 444455556666)的事件才能触发 Amazon SNS 主题。这是一项安全措施,可防止未经授权的账户向您的主题发送通知。

  • 其他服务支持 SourceAccount以下服务支持 SourceAccount 条件。当您想要根据原始账户限制访问您的 Amazon SNS 主题时,使用此条件至关重要。

    • Amazon API Gateway

    • Amazon CloudWatch

    • Amazon DevOps Guru

    • Amazon EventBridge

    • Amazon GameLift

    • Amazon Pinpoint SMS 和 Voice API

    • Amazon RDS

    • Amazon Redshift

    • Amazon S3 Glacier

    • Amazon SES

    • Amazon Simple Storage Service

    • AWS CodeCommit

    • AWS Directory Service

    • AWS Lambda

    • AWS Systems Manager Incident Manager

  • 测试和验证。应用策略后,通过在 Amazon S3 存储桶中触发事件并确认该事件已成功发布到您的 Amazon SNS 主题来测试设置。这将有助于确保您的策略配置正确。

  • 安全最佳实践。定期审查和审核您的 Amazon SNS 主题策略,确保它们符合您的安全要求。仅限可信账户和服务访问对于维护安全运营至关重要。

允许 Amazon SES 向其他账户拥有的主题发布

您可以允许另一个 AWS 服务 发布到另一个 AWS 账户拥有的主题。假设您登录了 111122223333 账户,打开了 Amazon SES 并创建了一封电子邮件。要将有关此电子邮件的通知发布到 444455556666 账户拥有的 Amazon SNS 主题,您需要创建一个如下所示的策略。为此,您需要提供有关委托人(其他服务)和每个资源的所有权的信息。Resource 语句提供主题 ARN,其中包括主题所有者的账户 ID 444455556666。"aws:SourceOwner": "111122223333" 语句指定您的账户拥有该电子邮件。

{ "Version": "2008-10-17", "Id": "__default_policy_ID", "Statement": [ { "Sid": "__default_statement_ID", "Effect": "Allow", "Principal": { "Service": "ses.amazonaws.com" }, "Action": "SNS:Publish", "Resource": "arn:aws:sns:us-east-2:444455556666:MyTopic", "Condition": { "StringEquals": { "aws:SourceOwner": "111122223333" } } } ] }

向 Amazon SNS 发布事件时,以下服务支持 aws:SourceOwner

  • Amazon API Gateway

  • Amazon CloudWatch

  • Amazon DevOps Guru

  • Amazon GameLift

  • Amazon Pinpoint SMS 和 Voice API

  • Amazon RDS

  • Amazon Redshift

  • Amazon SES

  • AWS CodeCommit

  • AWS Directory Service

  • AWS Lambda

  • AWS Systems Manager Incident Manager

aws:SourceAccountaws:SourceOwner

重要

aws:SourceOwner 已弃用,新服务只能通过 aws:SourceArnaws:SourceAccount 与 Amazon SNS 集成。对于目前支持 aws:SourceOwner 的现有服务,Amazon SNS 仍保持向后兼容性。

aws:SourceAccountaws:SourceOwner 条件键由一些 AWS 服务在它们发布到 Amazon SNS 主题时设置。当支持时,该值将是 12 位数的 AWS 账户 ID,服务将代表该账户发布数据。一些服务支持其中一项,一些服务支持另一项。

允许 AWS Organizations 中的组织中的账户发布到其他账户中的主题

AWS Organizations 服务可帮助您集中管理账单、控制访问权限和安全性以及跨 AWS 账户 共享资源。

您可以在 Organizations 控制台中找到您的组织 ID。有关更多信息,请参阅从管理账户查看组织的详细信息

在此示例中,组织 myOrgId 中的任何 AWS 账户 都可以发布到账户 444455556666 中的 Amazon SNS 主题 MyTopic。该策略使用 aws:PrincipalOrgID 全局条件键检查组织 ID 值。

{ "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "SNS:Publish", "Resource": "arn:aws:sns:us-east-2:444455556666:MyTopic", "Condition": { "StringEquals": { "aws:PrincipalOrgID": "myOrgId" } } } ] }

允许任何 CloudWatch 告警发布到不同账户中的主题

在这种情况下,将允许账户 111122223333 中的任何 CloudWatch 告警发布到账户 444455556666 中的 Amazon SNS 主题。

{ "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "SNS:Publish", "Resource": "arn:aws:sns:us-east-2:444455556666:MyTopic", "Condition": { "ArnLike": { "aws:SourceArn": "arn:aws:cloudwatch:us-east-2:111122223333:alarm:*" } } } ] }

仅限从特定 VPC 终端节点发布到 Amazon SNS 主题

在这种情况下,账户 444455556666 中的主题只允许从具有 ID vpce-1ab2c34d 的 VPC 终端节点发布。

{ "Statement": [{ "Effect": "Deny", "Principal": "*", "Action": "SNS:Publish", "Resource": "arn:aws:sns:us-east-2:444455556666:MyTopic", "Condition": { "StringNotEquals": { "aws:sourceVpce": "vpce-1ab2c34d" } } }] }