【问题标题】:How do I add permissions on an AWS SQS Queue?如何在 AWS SQS 队列上添加权限?
【发布时间】:2026-01-22 09:25:02
【问题描述】:

通过以下代码,我可以使用我的 AWS 帐号添加权限,但队列没有收到来自 SNS 的任何消息。

AddPermissionRequest addPermissionRequest = new AddPermissionRequest();
addPermissionRequest.ActionName.Add("SendMessage");
addPermissionRequest.ActionName.Add("ReceiveMessage");
addPermissionRequest.QueueUrl = queueUrl;
addPermissionRequest.Label = General.IpAddressAWSFriendly;
addPermissionRequest.AWSAccountId.Add(AWS_ACCOUNT_ID);
sqs.AddPermission(addPermissionRequest);

但是,当我尝试通过通配符 (*) 为所有人设置权限时:

addPermissionRequest.AWSAccountId.Add("*");

它给了我一个错误。如果我在 AWS SQS 控制台中手动添加权限并指定

SendMessage
ReceiveMessage

对于允许的操作和原则,我将其设置为“所有人”,队列确实接收来自我的 SNS 主题的消息。所以,很明显,我做错了什么,但我再也看不到了。

任何帮助都会很棒!我希望亚马逊有示例,SDK 附带的示例没有显示任何有关设置策略或权限的内容。在线文档中也没有显示任何内容。令人沮丧。

【问题讨论】:

    标签: c# amazon-web-services clojure permissions amazon-sqs


    【解决方案1】:

    幸运的是,我自己想通了,因为我在这里没有收到任何回复。我真的希望 Amazon 能够为 .Net 框架上的 C# 开发人员提供更好的文档,而不仅仅是脚本小子。

    无论如何,我最终创建了一个完整的 Policy 对象并将其传递给 SQS。我使用的是 AWS SDK v1.5 版本,而不是较新的 2.0(目前处于测试阶段),只是因为它现在可以工作,而且我懒得将其更改为较新的 2.0 版本。

    以下是您需要以编程方式在 C# 中为 SQS 队列创建策略的代码,条件是仅将该队列与 SNS 主题一起使用:

            // 4. Set the queue policy to allow SNS to publish messages
            ActionIdentifier[] actions = new ActionIdentifier[2];
            actions[0] = SQSActionIdentifiers.SendMessage;
            actions[1] = SQSActionIdentifiers.ReceiveMessage;
            Policy sqsPolicy = new Policy()
                .WithStatements(new Statement(Statement.StatementEffect.Allow)
                                    .WithPrincipals(Principal.AllUsers)
                                    .WithResources(new Resource(queueArn))
                                    .WithConditions(ConditionFactory.NewSourceArnCondition(_AWSSNSArn))
                                    .WithActionIdentifiers(actions));
            SetQueueAttributesRequest setQueueAttributesRequest = new SetQueueAttributesRequest();
            List<Amazon.SQS.Model.Attribute> attributes = new List<Amazon.SQS.Model.Attribute>();
            Amazon.SQS.Model.Attribute attribute = new Amazon.SQS.Model.Attribute();
            attribute.Name = "Policy";
            attribute.Value = sqsPolicy.ToJson();
            attributes.Add(attribute);
            setQueueAttributesRequest.QueueUrl = queueUrl;
            setQueueAttributesRequest.Attribute = attributes;
            sqs.SetQueueAttributes(setQueueAttributesRequest);
    

    我希望这对某人有所帮助。

    【讨论】:

    • 只是说我同意你的观点并没有太多的例子——我一直在研究如何设置——ReceiveMessageWaitTimeSeconds,我只是一直碰壁——我可以在控制台,但找不到有关如何设置它的代码示例 - 我认为它会很简单!
    • @anna 听起来您正在尝试对 SQS 队列进行长轮询。您遇到了哪些具体问题?您是否发布了一个 SO 问题?也许我可以帮忙。
    • 我正在尝试进行长轮询我知道如何手动设置它但是当我在代码中创建队列时我需要设置它我有这个创建队列 var sqsRequest = new CreateQueueRequest(); sqsRequest.QueueName = "Bin2AutomationQ"; var createQueueResponse = sqs.CreateQueue(sqsRequest); myQueueUrl = createQueueResponse.CreateQueueResult.QueueUrl;但不确定如何将 ReceiveMessageWaitTimeSeconds 设置为 20
    • @anna * 不允许我在评论中添加代码,甚至不允许添加新行,所以我在我的博客上发布了如何在此处设置长轮询队列:thomasjaeger.wordpress.com/2013/10/21/…
    • 谢谢!你拯救了我的一天 =)
    【解决方案2】:

    下面是在 Clojure 中使用 amazonica 的方法:

    (require '[amazonica.aws.sqs :as sqs]
             '[amazonica.core :as aws)
    (import '(com.amazonaws.auth.policy Statement Statement$Effect
                                        Principal
                                        Policy
                                        Resource
                                        Condition
                                        Action)
            '(com.amazonaws.auth.policy.actions SQSActions)
            '(com.amazonaws.auth.policy.conditions ConditionFactory))
    
    (aws/defcredential "access-key" "secret-key" "us-east-1")
    
    (def topic-arn "arn:aws:sns:us-east-1:123:foo")
    (def queue-url "https://sqs.us-east-1.amazonaws.com/123/bar")
    (def queue-arn (-> queue-url sqs/get-queue-attributes :QueueArn))
    
    (def policy (Policy.
                       (str queue-arn "/SQSDefaultPolicy")
                       [(doto (Statement. Statement$Effect/Allow)
                           (.setPrincipals [Principal/AllUsers])
                           (.setResources [(Resource. queue-arn)])
                           (.setConditions [(ConditionFactory/newSourceArnCondition topic-arn)])
                           (.setActions [SQSActions/SendMessage]))]))
    
    (sqs/set-queue-attributes queue-url {"Policy" (.toJson policy)})
    

    【讨论】:

      【解决方案3】:

      以下是我如何动态创建具有匿名读取访问权限的队列。只需根据需要添加额外的 ActionIdentifiers:

          public static String TestQueueCreate(String name) {
      
              AmazonSQSClient sqs = new AmazonSQSClient(region: Amazon.RegionEndpoint.USEast1);
              CreateQueueResponse create = sqs.CreateQueue(name);
      
              Policy policy = new Policy() {
                  Statements = new List<Statement>() {
                      new Statement(StatementEffect.Allow) {
                          Principals = new List<Principal>() { Principal.AllUsers },
                          Actions = new List<ActionIdentifier>() { SQSActionIdentifiers.ReceiveMessage }
                      }
                  }
              };
      
              Dictionary<String,String> queueAttributes = new Dictionary<String, String>();
              queueAttributes.Add(QueueAttributeName.Policy.ToString(), policy.ToJson());
              sqs.SetQueueAttributes(new SetQueueAttributesRequest(create.QueueUrl, queueAttributes));
      
              return create.QueueUrl;
          }
      

      【讨论】:

        【解决方案4】:

        先前创建的权限没有按预期工作的资源。这是获取arn的更正:

            public static String TestQueueCreate(String name) {
        
                AmazonSQSClient sqs = new AmazonSQSClient(region: Amazon.RegionEndpoint.USEast1);
                CreateQueueResponse create = sqs.CreateQueue(name);
        
                String arn = sqs.GetQueueAttributes(create.QueueUrl, new List<String>() { "QueueArn" }).Attributes["QueueArn"];
        
                Policy policy = new Policy() {
                    Statements = new List<Statement>() {
                        new Statement(StatementEffect.Allow) {
                            Principals = new List<Principal>() { new Principal("*") },
                            Actions = new List<ActionIdentifier>() {
                                new ActionIdentifier("SQS:ReceiveMessage"),
                                new ActionIdentifier("SQS:SendMessage")
                            },
                            Resources = new List<Resource>() { new Resource(arn) }
                        }
                    },
        
                };
        
                Dictionary<String,String> queueAttributes = new Dictionary<String, String>();
                queueAttributes.Add(QueueAttributeName.Policy.ToString(), policy.ToJson());
                sqs.SetQueueAttributes(new SetQueueAttributesRequest(create.QueueUrl, queueAttributes));
        
                return create.QueueUrl;
            }
        

        【讨论】: