首页 文章

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

提问于
浏览
0

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

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

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

这就是我想要的:

Bucket-name: 测试桶

  • Action: 在test-bucket的根目录中创建文件夹 . Desired Result: 否认

  • Action: 在test-bucket的根目录中上传随机文件 . Desired Result: 否认

  • Action: 在test-bucket的现有"folder1"文件夹(test-bucket / folder1 / file1)上传文件"file1" . Desired Result: 成功

  • Action: 在test-bucket的现有"folder1"文件夹(test-bucket / folder1 / sub-folder1 /)中创建文件夹"sub-folder1" . Desired Result: 成功

2 回答

  • 3

    你的概念模型存在缺陷 .

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

    这是不正确的 .

    这是正确的版本:

    • S3服务和API没有文件夹的概念 .

    • S3对象没有任何真正意义上的层次结构 .

    • S3控制台是唯一具有文件夹概念的实体 .

    • S3服务和API支持前缀,分隔符和公共前缀的概念 .

    当对API的列表对象请求附带指定的前缀时,只返回具有以该前缀开头的键的对象,而不管前缀后的对象键中是否有任何 / .

    当列表对象请求附带前缀和分隔符(通常为 / )时,API仅返回其键与给定前缀匹配且在键中没有后续 / (在请求中指定的前缀之后)的对象 . 这些类似于"files in the folder."

    匹配给定前缀但具有后续(在指定前缀之后) / 的任何对象的键的前缀被合并到其前缀的唯一列表,被截断到它们的下一个 / . 这些是常见的前缀,类似于"folders in the folder."

    但事实上,没有任何东西真的“在”其他任何东西 .

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

    控制台通过允许你进一步增加幻觉 - 但它实际上不是一个文件夹,甚至不需要它 . 它只是一个空对象,其中一个键的最后一个字符是 / . S3的正常操作不需要此对象,但是为方便起见而创建,因此您可以导航"into" "empty folder"并上载文件"into"空文件夹 .

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

    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服务测试它不知道哪些实际上不需要存在的东西 .

    因此,技术上不可能完全按照你的要求行事;然而,似乎有一个有限的解决方法 . 主要限制是您不能指定"the folder must exist,"但您可以指定"the object key prefix must match a predefined set of patterns."

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

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

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

    当然,限制是使另一个文件夹符合访问权限需要修改策略 .

    这可能也有效,但请谨慎行事:

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

    直观地看起来这可能会起作用,但这里的缺陷 - 假设 ?*/?* 有效(it seems to be)并且 ?* 的方式不匹配0个字符 - 这是允许用户创建新的(伪)根目录中的文件夹,只要它们使用API同时在其中创建一个名称至少有一个字符长的内容,也就是说,如果它已经存在,则创建一个带有键 pics/cat.jpg "creates"文件夹的对象,如上所述 . 从控制台,这应该可以防止在根目录中创建新文件夹,但是从API中它不会产生这样的限制 .

  • 0

    谢谢你的精心回复@Michael . 您完全正确地说API和CLI调用可以在非空时继续创建根级文件夹 . 控制台和S3浏览器访问按预期工作 . 这是妥协,但它是我们能够达到我们想要的最接近的 . 这是我正在使用的存储桶策略:

    {
      "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/?*/?*"
        }
      ]
    }
    

相关问题