我目前正在使用C#工作,但是我相信在任何AWS开发工具包中都会出现同样的问题。
我正在尝试以编程方式验证某个主题可以将消息发送到队列(实际上并没有尝试添加许可,只是检查它是否存在)。
到目前为止,我发现的唯一方法是扫描队列策略以查找与主题ARN相匹配的语句,即:
policy.Statements.Any(
statement =>
statement.Effect == Statement.StatementEffect.Allow
&& statement.Principals.Any(
principal => string.Equals(
principal.Id,
Principal.AllUsers.Id,
StringComparison.OrdinalIgnoreCase))
&& statement.Actions.Any(
identifier => string.Equals(
identifier.ActionName,
SQSActionIdentifiers.SendMessage.ActionName,
StringComparison.OrdinalIgnoreCase))
&& statement.Resources.Any(resource => resource.Id == queueArn)
&& statement.Conditions.Any(
condition =>
(string.Equals(
condition.Type,
ConditionFactory.StringComparisonType.StringLike.ToString(),
StringComparison.OrdinalIgnoreCase)
|| string.Equals(
condition.Type,
ConditionFactory.StringComparisonType.StringEquals.ToString(),
StringComparison.OrdinalIgnoreCase)
|| string.Equals(
condition.Type,
ConditionFactory.ArnComparisonType.ArnEquals.ToString(),
StringComparison.OrdinalIgnoreCase)
|| string.Equals(
condition.Type,
ConditionFactory.ArnComparisonType.ArnLike.ToString(),
StringComparison.OrdinalIgnoreCase))
&& string.Equals(
condition.ConditionKey,
ConditionFactory.SOURCE_ARN_CONDITION_KEY,
StringComparison.OrdinalIgnoreCase)
&& condition.Values.Contains(topicArn)))
这与调用SubscribeQueueAsync时在AWS开发工具包中的完成方式类似(请参见corresponding code on github)。
我对这种方法的问题是感觉如何脆弱。例如,如果条件具有通配符怎么办?如果存在针对特定主体而不是全部主体的授权怎么办?
所以我想我可能会使用IAM,特别是SimulatePrincipalPolicy或SimulateCustomPolicy。它们可以用于吗?
我认为是这样的:
var simulatePrincipalPolicyRequest = new SimulatePrincipalPolicyRequest
{
ActionNames = { SQSActionIdentifiers.SendMessage.ActionName },
ResourceArns = { queueArn },
PolicySourceArn = topicArn
};
var response = await _iamService.SimulatePrincipalPolicyAsync(
request: simulatePrincipalPolicyRequest,
cancellationToken: cancellationToken);
本来可以,但是我得到Amazon.IdentityManagement.Model.InvalidInputException : Could not extract entity from ARN : arn:aws:sns:eu-west-1:<accountid>:<topicname>
。
我认为可能与CallerArn属性有关?我注意到,队列从主题(AIDA *****************)接收到的消息中,发件人帐户ID的用户密钥似乎总是相同。< / p>
不知道我在尝试什么...
答案 0 :(得分:0)
开箱即用,您不能使用SimulatePrincipalPolicy
(docs)检查服务是否具有IAM权限:
该实体可以是IAM用户,组或角色。如果指定用户,则模拟还将包括附加到该用户所属组的所有策略。
如果您查看CallerArn
类的SimulatePolicyRequest
property,则会得到:
您只能指定IAM用户的ARN。您不能指定 假定角色,联合用户或服务主体的ARN。
我使用Powershell SDK进行了测试-该软件在.net上运行并出现了相同的错误。
Test-IAMPrincipalPolicy -ActionName 'sqs:SendMessage' -PolicySourceArn arn:aws:sns:::sim-test -ResourceArn arn:aws:sqs:::sim-test
Test-IAMPrincipalPolicy : Could not extract entity from ARN : arn:aws:sns:::sim-test
可能的解决方案 该功能确实适用于IAM Service Roles。您可以在IAM中创建服务角色,该角色具有delegates的SNS权限以将消息发送到SQS。如果您可以为SNS创建服务角色,则可以使用SimulatePrincipalPolicy函数。
我再次在PS中对此进行了测试。首先,我在IAM控制台中创建了服务角色:
您现在已将某些CloudWatch权限委派给SNS。我们将在几秒钟内删除它,但是现在我至少可以调用该函数,并传递策略ARN:
Test-IAMPrincipalPolicy -ActionName 'sqs:SendMessage' -PolicySourceArn arn:aws:iam:::role/sim-test-servicerole -ResourceArn arn:aws:sqs:::sim-test
EvalActionName : sqs:SendMessage
EvalDecision : implicitDeny
EvalDecisionDetails : {}
EvalResourceName : arn:aws:sqs:::sim-test
MatchedStatements : {}
MissingContextValues : {}
OrganizationsDecisionDetail :
ResourceSpecificResults : {arn:aws:sqs:::sim-test}
请注意,EvalDecision是隐式拒绝。
现在,您可以编辑创建的角色。删除Cloudwatch策略并添加相关的SQS策略并再次测试:
EvalActionName : sqs:SendMessage
EvalDecision : allowed
EvalDecisionDetails : {}
EvalResourceName : arn:aws:sqs:::sim-test
MatchedStatements : {AmazonSQSFullAccess}
MissingContextValues : {}
OrganizationsDecisionDetail :
ResourceSpecificResults : {arn:aws:sqs:::sim-test}
如果您不能/不会为SNS设置服务角色,那么我认为唯一的方法就是像已经完成的那样抓取策略。
在进一步测试之后,即使上面的功能起作用了,我实际上也无法让SNS进入SQS!因此,这是一个错误的肯定,我认为您将重新取消该政策。