S3存储桶策略:在“公共存储桶"中,将子文件夹设为私有

问题描述:

我有一个装满东西的水桶,里面的东西大部分都是公开的.但是,只有一个文件夹(也称为前缀")只能由经过身份验证的IAM用户访问.

I have a bucket filled with contents that need to be mostly public. However, there is one folder (aka "prefix") that should only be accessible by an authenticated IAM user.

{
  "Statement": [
    {
      "Sid": "AllowIAMUser",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::bucket/prefix1/prefix2/private/*",
      "Principal": {
        "AWS": [
          "arn:aws:iam::123456789012:user/bobbydroptables"
        ]
      }
    },
    {
      "Sid": "AllowAccessToAllExceptPrivate",
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::bucket/*",
      "Condition": {
        "StringNotLike": {
          "s3:prefix": "prefix1/prefix2/private/"
        }
      },
      "Principal": {
        "AWS": [
          "*"
        ]
      }
    }
  ]
}

当我尝试保存此策略时,我从AWS收到以下错误消息:

When I try to save this policy I get the following error messages from AWS:

Conditions do not apply to combination of actions and resources in statement -
  Condition "s3:prefix"
  and action "s3:GetObject"
  in statement "AllowAccessToAllExceptPrivate"

显然,此错误专门适用于第二条语句.

Obviously this error applies specifically to the second statement. Is it not possible to use the "s3:prefix" condition with the "s3:GetObject" action?

是否有可能占用公共存储桶的一部分,并使之仅由经过身份验证的用户访问?

Is it possible to take one portion of a public bucket and make it accessible only to authenticated users?

万一重要,则只能通过api以只读方式访问此存储桶.

In case it matters, this bucket will only be accessed read-only via api.

此问题类似于>仅针对公共限制的Amazon S3存储桶策略,除了我试图通过其他方法解决问题.

This question is similar to Amazon S3 bucket policy for public restrictions only, except I am trying to solve the problem by taking a different approach.

在大量阅读了AWS文档以及策略编辑器中的许多试验和错误排列之后,我认为我找到了一个合适的解决方案.

After much digging through AWS documentation, as well as many trial and error permutations in the policy editor, I think I have found an adequate solution.

显然,AWS提供了一个名为 NotResource 的选项(当前在策略生成器"中找不到).

Apparently, AWS provides an option called NotResource (not found in the Policy Generator currently).

The NotResource element lets you grant or deny access to all but a few
of your resources, by allowing you to specify only those resources to
which your policy should not be applied.

有了这个,我什至不需要玩弄条件.这意味着以下语句将在存储桶策略中起作用:

With this, I do not even need to play around with conditions. This means that the following statement will work in a bucket policy:

{
  "Sid": "AllowAccessToAllExceptPrivate",
  "Action": [
    "s3:GetObject",
    "s3:GetObjectVersion"
  ],
  "Effect": "Allow",
  "NotResource": [
    "arn:aws:s3:::bucket/prefix1/prefix2/private/*",
    "arn:aws:s3:::bucket/prefix1/prefix2/private"
  ],
  "Principal": {
    "AWS": [
      "*"
    ]
  }
}