為什麼無法發佈或訂閱 Amazon SNS 主題?

上次更新日期:2021 年 11 月 4 日

我無法發佈或訂閱 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 主題的存取政策,使其包含下列許可聲明:

{
    "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 資源名稱 (ARN) 的任何人,透過服務端點將訊息發佈至主題。您可以新增全域條件金鑰,以限制特定資源的發佈許可。下列範例使用 arnLike 條件運算子和 aws:SourceArn 全域條件金鑰。如需詳細資訊,請參閱 Amazon SNS 存取控制範例案例

將 Amazon SNS 發佈許可限制在特定資源的 IAM 政策範例

重要事項:用資源的 AWS 區域取代 <region> 。用您的帳戶 ID 取代 <account-id>。用資源名稱取代 <resource-name>

{
    "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 政策聲明連接至 IAM 實體,以允許實體執行 "sns:Subscribe""sns:Publish" 動作。如需指示,請參閱新增並移除 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 主題的存取政策?

以下是 Amazon SNS 主題存取政策範例,允許 IAM 實體訂閱並發佈至 SNS 主題:

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

注意:Principal 可以是以 IAM 身分為基礎的使用者或角色,或者是 AWS 帳戶號碼。如需詳細資訊,請參閱 AWS JSON 政策元素:Principal

如果 IAM 實體和 SNS 主題位於同一個帳戶

執行下列任一項操作,但不同時執行兩者:

將 IAM 政策聲明連接至 IAM 實體,以允許實體執行 "sns:Subscribe""sns:Publish" 動作。

-或-

將 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 政策聲明範例

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