首页 > 解决方案 > AWS S3 StringLike 条件阻止对存储桶的请求

问题描述

我有以下 s3 IAM 政策。它旨在允许我从存储桶中的 temp/prod/tests 位置复制文件或将文件放入存储桶中。

在策略中,我添加了 StringLike 条件,我希望允许策略中的权限在对象前缀包含temp/prod/tests.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "s3:ReplicateObject",
                "s3:PutObject",
                "s3:ListBucket",
                "s3:GetObjectAcl",
                "s3:GetObject",
                "s3:GetBucketLocation",
                "s3:GetBucketAcl",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::MYBUCKET/temp/prod/tests/*",
                "arn:aws:s3:::MYBUCKET"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "temp/prod/tests/*",
                        "temp/prod/tests/"
                    ]
                }
            }
        }
    ]
}

我的问题是该条件阻止我复制 temp/prod/tests/ 下的任何内容,或将任何新对象放入此存储桶中的此位置下方。

 $ aws s3 cp --recursive s3://MYBUCKET/temp/prod/tests/ /tmp
download failed: s3://MYBUCKET/temp/prod/tests/testfiles/testfile to ../../../tmp/testfiles/testfile An error occurred (AccessDenied) when calling the GetObject operation: Access Denied

$ aws s3 cp /tmp/test s3://MYBUCKET/temp/prod/tests/
 An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

如果我删除条件,我可以按预期复制文件。

我不明白为什么条件不起作用,因为据我所知,我提出的请求与条件的前缀相匹配。

有谁知道为什么这不像我预期的那样工作?

标签: amazon-web-servicesamazon-s3amazon-iam

解决方案


我认为这里的部分困惑是您期望s3:prefix在 CopyObject 操作期间存在和可测试。它在 ListBucket 操作期间存在,我认为这可能是它存在的唯一操作。记录了 S3 的条件键,但文档似乎没有包含在哪些 API 操作期间存在哪些键的矩阵。

具体来说,我相信s3:prefix在实际 CopyObject 操作期间将不存在,这意味着 IAM 会将其视为values do not match,因此条件测试失败并且 CopyObject 操作被拒绝。

AWS策略评估逻辑相当简单且定义明确,但存在AWS 全局条件上下文键的上下文没有明确定义,或者至少没有充分记录。也很难准确地确定为什么给定的 API 操作在事后被拒绝(即聚合策略的哪一部分导致失败),这使得编写和测试复杂的策略变得困难。

理想情况下,您会知道哪些键存在于哪些操作中,但这似乎没有记录在案。解决这个问题的一种方法是测试(看看什么有效,什么无效)。另一种方法是使用...IfExists条件检查,但这实际上是为与可选的策略键一起使用而设计的,而不是甚至不相关的策略键。例如,当您使用StringLikeIfExists时:

如果策略密钥存在于请求的上下文中,则按照策略中指定的方式处理密钥[即执行 StringLike 测试]。如果键不存在,则将条件元素评估为真。

就您的政策而言,我建议:

  • 将存储桶资源与存储桶操作一起使用,将对象资源与对象操作一起使用(现在,您将它们混合在一起)
  • 将您的前缀条件限制为 ListBucket 操作
  • 无需使 GetObject 或 PutObject 有条件,只需指明允许这些操作的资源 ARN(例如arn:aws:s3:::MYBUCKET/temp/prod/tests/*

推荐阅读