为什么我无法发布或订阅 Amazon SNS 主题?

2 分钟阅读
0

我无法发布或订阅 Amazon Simple Notification Service (Amazon SNS) 主题。我该如何解决此问题?

简短描述

若没有所需权限,AWS Identity and Access Management (IAM) 资源或身份将无法发布或订阅 Amazon SNS 主题。

要授予发布或订阅 Amazon SNS 主题所需的 IAM 权限,请根据您的使用案例执行以下操作之一。

**注意:**Amazon SNS 使用基于 IAM 身份的访问策略和基于 Amazon SNS 资源的访问策略来授予对 SNS 主题的访问权限。您可以使用 IAM 策略限制用户或角色对 Amazon SNS 操作和主题的访问。IAM 策略只能限制 AWS 账户内的用户访问,而不能限制其他 AWS 账户的访问。有关更多信息,请同时参阅 IAM 和 Amazon SNS 策略

解决方法

向其他 AWS 服务授予发布到 Amazon SNS 主题的权限

您的 Amazon SNS 主题的基于资源的策略必须允许其他 AWS 服务向主题发布消息。查看主题的访问策略以确认它具有所需的权限,并根据需要添加这些权限。

要添加所需的权限,请编辑 Amazon SNS 主题的访问策略,使其包含以下权限声明。
重要提示:将 <service> 替换为 AWS 服务。

{
    "Sid": "Allow-AWS-Service-to-publish-to-the-topic",
    "Effect": "Allow",
    "Principal": {
        "Service": "<service>.amazonaws.com"
    },
    "Action": "sns:Publish",
    "Resource": "arn:aws:sns:your_region:123456789012:YourTopicName"
}

**重要提示:**这些权限允许有权访问您的 SNS 主题的 Amazon Resource Name (ARN) 的任何人通过服务终端节点向主题发布消息。您可以添加全局条件键来限制对特定资源的发布权限。以下示例使用 arnLike 条件运算符和 aws:SourceArn 全局条件键。有关更多信息,请参阅 Amazon SNS 访问控制的示例案例

将 Amazon SNS 发布权限限制到特定资源的 IAM 策略示例

**重要提示:**将 <region> 替换为资源的 AWS 区域。将 <account-id> 替换为您的账户 ID。将 <resource-name> 替换为资源的名称。将 <service> 替换为 AWS 服务。

{
    "Sid": "Allow-AWS-Service-to-publish-to-the-topic",
    "Effect": "Allow",
    "Principal": {
        "Service": "<service>.amazonaws.com"  
    },
    "Action": "sns:Publish",
    "Resource": "arn:aws:sns:your_region:123456789012:YourTopicName",
    "Condition": {
        "ArnLike": {
            "aws:SourceArn": "arn:aws:<service>:<region>:<account-id>:<resource-type>:<resource-name>"
        }
    }
}

注意:Amazon S3 不支持 FIFO SNS 主题。如果主题策略中有 S3 ARN,请确保它不是存储桶文件夹的路径。例如:arn:aws:s3:*:*:mys3-bucket/*

允许 IAM 用户或角色订阅和发布到 Amazon SNS 主题

默认情况下,只有主题拥有者可以发布或订阅主题。要允许其他 IAM 实体订阅发布到您的主题,您的主题的基于身份的策略必须授予所需的权限。

**重要提示:**确保 IAM 实体的策略或 SNS 主题的访问策略均未明确拒绝访问 SNS 资源。有关更多信息,请参阅显式拒绝与隐式拒绝之间的区别

如果 IAM 实体和 SNS 主题位于不同的 AWS 账户中

请执行以下两项操作:

1.    将 IAM 策略声明附加到允许实体运行“sns:Subscribe”“sns:Publish”操作的 IAM 实体。有关说明,请参阅添加和删除 IAM 身份权限

以下是一个基于 IAM 身份的策略示例,该策略允许 IAM 实体订阅和发布 SNS 主题:

{
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sns:Publish",
                "sns:Subscribe"
            ],
            "Resource": "arn:aws:sns:your_region:123456789012:YourTopicName"
        }
    ]
}

2.    将 SNS 策略声明附加到您主题的访问策略,以允许 IAM 实体运行“sns:Subscribe”“sns:Publish”操作。有关说明,请参阅如何编辑我的 Amazon SNS 主题的访问策略?

以下是允许 IAM 实体订阅和发布 SNS 主题的 Amazon SNS 主题访问策略示例:

{
    "Statement": [
        {
            "Sid": "Allow-SNS-Permission",
            "Effect": "Allow",
            "Principal": {
                "AWS": "111122223333"
            },
            "Action": [
                "sns:Publish",
                "sns:Subscribe"
            ],
            "Resource": "arn:aws:sns:your_region:123456789012:YourTopicName"
        }
    ]
}

注意:****委托人可以是基于 IAM 身份的用户或角色,也可以是 AWS 账号。有关更多信息,请参阅 AWS JSON 策略元素:Principal

如果 IAM 实体和 SNS 主题在同一账户中

请执行以下任一操作,但不能同时执行两项操作:

将 IAM 策略声明附加到允许实体运行“sns:Subscribe”和“sns:Publish”操作的 IAM 实体。

-或者-

将 SNS 策略声明附加到您主题的访问策略,以允许 IAM 实体运行“sns:Subscribe”和“sns:Publish”操作。

有关策略声明示例,请参阅本文的如果 IAM 实体和 SNS 主题位于不同的 AWS 账户中部分。

(对于激活服务器端加密 (SSE) 的主题)确认您的主题有必要的 AWS Key Management (AWS KMS) 权限

如果您的主题已激活 SSE,则您的 Amazon SNS 主题必须使用客户管理的 AWS KMS 密钥。此 KMS 密钥必须包含自定义密钥策略,此策略授予其他 AWS 服务足够的密钥使用权限。

以下权限是最低要求:
“kms:Decrypt”
“kms:GenerateDataKey*”

要设置必要的 AWS KMS 权限,请执行以下操作:

1.    创建由客户管理的新 KMS 密钥,并且包含访问其他 AWS 服务所需的必要权限

2.    使用刚创建的自定义 KMS 密钥为您的 Amazon SNS 主题配置 SSE

3.    配置 AWS KMS 权限,允许其他 AWS 服务向您的已加密主题发布消息

允许其他 AWS 服务向加密 SNS 主题发布消息的 IAM 策略声明示例
重要提示:将 <service> 替换为 AWS 服务。

{
    "Sid": "Allow-a-service-to-use-this-key",
    "Effect": "Allow",
    "Principal": {
        "Service": "<service>.amazonaws.com"
    },
    "Action": [
        "kms:Decrypt",
        "kms:GenerateDataKey*"
    ],
    "Resource": "*"
}

相关信息

目标 SNS 主题的 IAM 策略

开启使用 AWS 成本异常检测

为 Amazon SQS 队列订阅 Amazon SNS 主题

使用 AWS Lambda 基于资源的策略

AWS 官方
AWS 官方已更新 2 年前