如何在AWS SQS队列上添加权限?

8

使用以下代码,我可以使用我的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随附的示例没有显示有关设置策略或权限的内容。在线文档中也没有显示任何内容。令人沮丧。
4个回答

11

很幸运的是,由于我在这里没有得到任何回应,所以我自己解决了这个问题。我真的希望亚马逊能够为C#开发人员提供更好的 .Net 框架文档,而不仅仅是给脚本小子。

无论如何,最终我创建了一个完整的策略对象并将其传递给了 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
@anna 听起来你正在尝试对 SQS 队列进行长轮询。你遇到了什么具体问题?你是否发布了一个Stack Overflow的问题?也许我可以帮忙。 - Thomas Jaeger
我正在尝试进行长轮询,我知道如何手动设置它,但我需要在代码中创建队列时设置它。我有以下代码来创建队列:var sqsRequest = new CreateQueueRequest(); sqsRequest.QueueName = "Bin2AutomationQ"; var createQueueResponse = sqs.CreateQueue(sqsRequest); myQueueUrl = createQueueResponse.CreateQueueResult.QueueUrl; 但不确定如何将ReceiveMessageWaitTimeSeconds设置为20。 - anna
2
@anna StackOverflow不允许我在评论中添加代码,甚至不能换行,所以我在我的博客上发布了如何设置长轮询队列的文章:http://thomasjaeger.wordpress.com/2013/10/21/how-to-turn-on-long-polling-on-an-aws-sqs-queue/ - Thomas Jaeger
谢谢!你救了我的一天 =) - Kralizek
@ThomasJaeger - 感谢你的超级问题和答案。它对我帮助很大。我已经苦思冥想了几天了。再次感谢! - Daniel Hollinrake

3

之前创建的权限没有指定资源,导致无法按预期工作。这里提供一个修正方法来获取该资源的 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;
    }

1

以下是我如何创建一个带有匿名读取权限的队列。只需根据需要添加额外的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;
    }

1

以下是使用amazonica在Clojure中完成此操作的方法:

(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)})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接