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

时间:2013-10-12 00:13:56

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

使用以下代码,我可以使用我的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 个答案:

答案 0 :(得分:11)

幸运的是,由于我在这里没有收到回复,所以我自己想出来了。我真的希望亚马逊能够为.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);

我希望这有助于某人。

答案 1 :(得分:2)

以前创建了没有资源的权限,该资源没有按预期工作。这是一个得到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;
    }

答案 2 :(得分: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)})

答案 3 :(得分:0)

以下是我使用匿名读取权限动态创建队列的方法。只需根据需要添加其他ActionIdentifier:

    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;
    }