【问题标题】:How to set ACL of all files in a folder in S3如何在 S3 中设置文件夹中所有文件的 ACL
【发布时间】:2017-12-13 15:54:32
【问题描述】:

我想使用 Java 授予对 S3 中文件夹内的所有文件的读取权限。我正在使用 TransferManager 进行文件夹上传,但我没有找到任何用于在目录级别设置 ACL 的 API

MultipleFileUpload upload = transferManager.uploadDirectory(bucketName, uploadDirectory, new File(folderName), true);

我知道我可以使用以下方法设置 S3 对象的 ACL: s3.setObjectAcl(bucketName, key, acl);

但我想一次对文件夹中的所有文件执行此操作。有什么办法吗?

【问题讨论】:

    标签: java amazon-web-services amazon-s3 aws-sdk


    【解决方案1】:

    在 S3 中,没有文件夹之类的东西,只有存储桶和密钥。为方便起见,共享公共前缀的键在控制台中组合在一起,但在引擎盖下,结构是完全扁平的。因此,无法为文件夹设置 ACL。但是有一些解决方法。

    使用存储桶策略

    根据您要授予的权限以及授予谁的权限,您可以使用存储桶策略授予对“文件夹”中所有键的访问权限。此示例允许任何人从存储桶my-bucket 中获取文件夹path/to/folder/ 下的任何密钥。这是来自文档的 list of possible actionslist of possible principals

    {
        "Version":"2012-10-17",
        "Statement":[
            {
                "Sid":"SimulateFolderACL",
                "Effect":"Allow",
                "Principal": "*",
                "Action":["s3:GetObject"],
                "Resource":["arn:aws:s3:::my-bucket/path/to/folder/*"]
            }
        ]
    }
    

    迭代 ACL 并将其应用于每个键

    您还可以遍历所有键并直接应用 ACL,就像您使用 s3.setObjectAcl(bucketName, key, acl) 提到的那样。您可以按文件夹前缀过滤密钥,因此您不必直接检查每个密钥名称。目录上传后,你可以这样做:

    // We only want the keys that are in the folder
    ListObjectsRequest listObjectsRequest = new ListObjectsRequest()
                                                .withBucketName("my-bucket")
                                                .withPrefix("path/to/folder/");
    ObjectListing objectListing;
    
    // Iterate over all the matching keys     
    do {
        objectListing = s3client.listObjects(listObjectsRequest);
        for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries())
        {
                // Apply the ACL
                s3.setObjectAcl(bucketName, key, acl);
        }
        listObjectsRequest.setMarker(objectListing.getNextMarker());
    } while (objectListing.isTruncated());
    

    【讨论】:

    • 这是一个高质量的答案,展示了真正的专业知识,并且指向“原则”和“行动”资源的链接是额外的接触,是我欣赏的那种彻底性的典范。
    • 我在我的应用程序中遇到了同样的问题,发现这个答案真的很有用。谢谢...
    • 我有一个担心,因为我正在上传大约十万个文件并想为它们设置权限。你认为会有性能开销吗?
    【解决方案2】:

    下面的简单方法可以公开读取存储桶中的所有对象。

    void makeObjectsPublic(AmazonS3 s3Client, String bucketName) {
    
        final Iterator<S3ObjectSummary> itr = s3Client.listObjects(bucketName).getObjectSummaries().iterator();
    
        while (itr.hasNext()) {
            s3Client.setObjectAcl(bucketName, itr.next().getKey(), CannedAccessControlList.PublicRead);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-06-07
      • 2016-01-11
      • 2019-05-12
      • 2021-04-20
      • 1970-01-01
      • 1970-01-01
      • 2013-04-04
      • 2011-05-15
      • 2017-01-15
      相关资源
      最近更新 更多