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



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

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

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

这是我想要的:

Bucket名称:测试Bucket

  • 操作:在测试存储桶的根目录中创建文件夹。期望结果:拒绝

  • 操作:在测试桶的根目录中上传随机文件。期望结果:拒绝

  • 操作:在测试bucket的现有"folder1"文件夹中上传文件"file1"(测试bucket/folder1/file1)。期望结果:成功

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

您的概念模型中存在缺陷。

我知道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

现在。。。如果你拿一个空桶,使用API(而不是控制台),你可以简单地PUT /foo/bar.txt,在控制台中得到完全相同的净结果——你看到一个名为"foo"的文件夹,其中包含"bar.txt"。该文件夹显示为,因为有一个前缀为foo/的对象。删除对象,文件夹将消失。

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

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

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

因此,从技术上讲,完全按照你的要求去做是不可能的;然而,似乎有一个有限的解决办法。主要限制是不能指定"文件夹必须存在",但可以指定"对象密钥前缀必须与预定义的一组模式匹配">

bucket或用户策略的相关部分可能看起来像这样。。。

"Action": "s3:PutObject",
"Resource": [ 
"arn:aws:s3:::examplebucket/taxdocuments/*",
"arn:aws:s3:::examplebucket/personnel/*",
"arn:aws:s3:::examplebucket/unicorns/*"
...
],

受此策略影响的用户可以在"examplebucket"bucket中创建任何以taxdocuments/或personal/或unicons/开头的对象,并且如果没有这些前缀,则无法创建对象。除此之外,只要其中一个前缀位于每个假文件夹的对象键的开头,就可以全天在"文件夹"中的"文件夹"创建控制台文件夹。

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

这可能也有效,但要谨慎:

"Resource": "arn:aws:s3:::examplebucket/?*/?*",

从直觉上看,这似乎可行,但这里的缺陷是——假设?*/?*有效(似乎有效),并且?不像*那样匹配0个字符——这允许用户在根目录中创建一个新的(伪)文件夹,只要他们同时使用API在其中创建名称至少为一个字符长的文件夹——也就是说,如上所述,使用关键字pics/cat.jpg创建一个对象会"创建"pics"文件夹(如果它还没有)。从控制台,这应该阻止在根目录中创建新文件夹,但从API,它不会施加这样的限制。

感谢您精心回复@Michael。API和CLI调用可以在非空时继续创建根级文件夹,这一说法完全正确。控制台和S3浏览器访问按预期工作。这是一种妥协,但这是我们最接近我们想要的。这是我正在使用的bucket策略:

{
"Version": "2012-10-17",
"Id": "Policy1486492608325",
"Statement": [
{
"Sid": "Stmt1486492495770",
"Effect": "Allow",
"Principal": {
"*"
},
"Action": [
"s3:DeleteObject",
"s3:Get*",
"s3:List*",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::test-storage",
"arn:aws:s3:::test-storage/*"
]
},
{
"Sid": "Stmt1486492534643",
"Effect": "Deny",
"Principal": {
"*"
},
"Action": [
"s3:DeleteObject",
"s3:PutObject"
],
"NotResource": "arn:aws:s3:::test-storage/?*/?*"
}
]
}

相关内容

  • 没有找到相关文章

最新更新