Amazon S3 策略阻止创建根级文件夹

uro*_*ver 1 amazon-s3 amazon-web-services amazon-iam

我们希望阻止 S3 用户在存储桶的根目录中创建新文件夹。换句话说,他们必须使用存储桶中的现有文件夹来上传或修改文件。如果愿意,他们可以选择在这些现有文件夹中创建子文件夹。

注意:使用 S3 策略。用户选择任何现有文件夹。他们没有指定的文件夹。

我知道 S3 将文件和文件夹视为对象,所以我不确定这是否可以完成,但我相信社区的潜力。

这就是我想要的:

桶名称:测试桶

  • 操作:在 test-bucket 的根目录中创建文件夹。 期望结果:拒绝

  • 操作:在 test-bucket 的根目录中上传随机文件。 期望结果:拒绝

  • 操作:在 test-bucket 的现有“folder1”文件夹 (test-bucket/folder1/file1) 中上传文件“file1”。 期望的结果:成功

  • 操作:在 test-bucket 的现有“folder1”文件夹 (test-bucket/folder1/sub-folder1/) 中创建文件夹“sub-folder1”。 期望的结果:成功

Mic*_*bot 7

您的概念模型存在缺陷。

我知道 S3 将文件和文件夹视为对象

这是不正确的。

这是正确的版本:

  • S3 服务和 API 没有文件夹的概念。
  • S3 对象没有任何真正意义上的层次结构。
  • S3 控制台是唯一具有文件夹概念的实体。
  • S3 服务和 API 支持前缀分隔符公共前缀的概念。

当对 API 的列表对象请求带有指定的前缀时,仅返回键以该前缀开头的对象,无论/其对象键中前缀之后的任何内容如何。

当列表对象请求附带前缀和分隔符(通常/)时,API 仅返回键与给定前缀匹配键中没有后续/(在请求中指定的前缀之后)的对象。这些类似于“文件夹中的文件”。

与给定前缀匹配但确实具有后续(在指定前缀之后)的任何对象的键的前缀/将合并为其前缀的唯一列表,并截断为其下一个/。这些是常见的前缀,类似于“文件夹中的文件夹”。

但事实上,没有什么是真正“存在于”其他事物之中的。

控制台通过从 API 的列表对象请求中读取公共前缀并将其显示为文件夹来创建文件夹的错觉。

控制台允许你“创建一个文件夹”,从而进一步加深了这种错觉——但它实际上不是一个文件夹,甚至不需要它。它只是一个空对象,其键的最后一个字符是/。S3 的正常操作不需要该对象,但创建它是为了方便,以便您可以导航“进入”“空文件夹”并将文件“上传到”该空文件夹。

然而,真正发生的事情是这样的:

Console: "create folder foo in the root of the bucket"
API: PUT /foo/
     Content-Length: 0

Console: "click folder foo"
API: GET /?prefix=foo/&delimiter=/

Console: "upload file bar.txt inside folder foo"
API: PUT /foo/bar.txt
Run Code Online (Sandbox Code Playgroud)

现在...如果您使用一个空桶,并使用 API(而不是控制台),您可以简单地在控制台中PUT /foo/bar.txt获得完全相同的最终结果- 您会看到一个名为“foo”的文件夹,其中包含“bar.txt” ”。显示该文件夹是因为存在带有前缀 的对象。删除该对象,文件夹就会消失。foo/

相反,如果您使用控制台从顶部执行此操作,一旦删除“bar.txt”,仍然会有文件夹“foo”,因为这实际上只是一个空对象,其唯一目的是使文件夹出现在控制台导航中当没有其他对象具有该公共前缀时。

所以,不...S3 不会将文件和文件夹都视为对象。S3控制台创建欺骗文件夹的对象,严格来说是为了辅助导航,而这里的神奇之处在于该对象的键以/. 另一方面,如果这些空对象不存在,控制台仍会显示对象,就像它们位于文件夹中一样。

然后你就会看到出现的问题。不能要求 S3 服务针对它不知道且实际上不需要存在的东西进行测试。

因此,从技术上讲,不可能完全按照您的要求进行操作;然而,似乎存在有限的解决方法。主要限制是您无法指定“文件夹必须存在”,但可以指定“对象键前缀必须与一组预定义的模式匹配”。

存储桶或用户策略的相关部分可能看起来像这样......

   "Action": "s3:PutObject",
   "Resource": [ 
      "arn:aws:s3:::examplebucket/taxdocuments/*",
      "arn:aws:s3:::examplebucket/personnel/*",
      "arn:aws:s3:::examplebucket/unicorns/*"
      ...
   ],
Run Code Online (Sandbox Code Playgroud)

受此策略影响的用户将能够在“examplebucket”存储桶中创建以taxdocuments/或personnel/或unicorns/开头的任何对象,并且无法创建没有这些前缀之一的对象。除此之外,只要这些前缀之一位于每个假文件夹的对象键的开头,就可以整天在“文件夹中”“文件夹中”创建控制台文件夹。

当然,限制是使另一个文件夹有资格访问需要修改策略。

这也可能有效,但请谨慎操作:

"Resource": "arn:aws:s3:::examplebucket/?*/?*",
Run Code Online (Sandbox Code Playgroud)

直观上这似乎可行,但这里的缺陷 - 假设?*/?*有效(似乎是)并且与?0 个字符不匹配*- 是这允许用户创建一个新的(伪)只要他们同时使用 API 在其中创建名称至少为一个字符长的内容,即使用键创建一个对象,就会pics/cat.jpg“创建”“pics”文件夹(如果该文件夹尚不存在),如下所示上面解释过。从控制台来看,这应该会阻止在根目录中创建新文件夹,但从 API 来看,它不会施加这样的限制。