使用CLI上传的文件夹没有正确的ACL(文件正常,只有文件夹有问题)

时间:2019-01-23 17:12:13

标签: amazon-web-services amazon-s3 acl aws-cli typo3-8.x

所以我正在尝试将资产从服务器转移到S3。

资产用于typo3环境。我的问题似乎出在S3上。由于某种原因,它没有提供对文件夹的适当访问权限。

已创建文件夹似乎可以正常使用,而通过浏览器或aws-cli上传的文件夹没有适当的权限。文件夹中的文件正常,可读且可写。但是TYPO3也需要文件夹。否则我到处都会遇到一些严重的错误。

这是我第一次使用S3,所以问题是:我在权限/设置上做错了吗,或者这是S3的已知问题?如果我搞砸了,有什么指针可以看?

这是我对该项目的存储桶策略。出于安全原因更改了用户/项目。

{
    "Version": "2012-10-17",
    "Id": "someID",
    "Statement": [
        {
            "Sid": "Read and write access for typo3 system",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::user/project"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::project/*"
        },
        {
            "Sid": "Public read access",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectAcl"
            ],
            "Resource": "arn:aws:s3:::project/*"
        }
    ]
}

我还添加了一个CORS配置,因为存储桶用作typo3系统的资产存储。域出于安全原因而更改。

<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>http://*.domain.com</AllowedOrigin>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

正如我所说,在typo3后端或S3管理控制台中手动创建文件夹效果很好。 在S3管理控制台中上传或与aws-cli同步都没有。

(对不起,由于“信誉”不足,无法发布图片)

https://imgur.com/lDlg4bP.png

https://i.imgur.com/UexKWLo.png

当选择包含其他此类损坏文件夹的文件夹时,TYPO3的“文件列表”模块中会显示橙色错误:

Error executing "GetObjectAcl" on "https://project.s3.eu-central-1.amazonaws.com/test_folder/uploaded_with_cli/?acl"; AWS HTTP error: Client error: 
`GET https://project.s3.eu-central-1.amazonaws.com/test_folder/uploaded_with_cli/?acl` resulted in a `404 Not Found` response: <?xml version="1.0" 
encoding="UTF-8"?> <Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message> (truncated...) NoSuchKey (client): The specified
 key does not exist. - <?xml version="1.0" encoding="UTF-8"?> <Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Key>
test_folder/uploaded_with_cli/</Key><RequestId>****randomkey****</RequestId><HostId>****randomsecretkey****</HostId></Error>

标记的 randomkey randomsecretkey 似乎是类似于id和secretkey的随机字符串,但是每个损坏的文件夹使用完全不同的密钥集都会产生这样的错误。我检查了一下,它们都不是用户的真实ID和秘密密钥。

2 个答案:

答案 0 :(得分:0)

S3没有目录(文件夹)的概念。 S3是一个对象存储,其中每个对象都由一个键标识。密钥可能是一个字符串,例如“ logs / 2014/06/04 / system.log”

S3之上的大多数图形用户界面(AWS CLI,AWS Console,Cloudberry,Transmit等...)将“ /”字符解释为目录分隔符,并按原样显示目录中的文件列表结构。

但是,在内部,没有目录的概念,S3具有统一的名称空间。有关更多详细信息,请参见http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html

鉴于此,通常无法在文件夹上定义权限,因为S3上没有文件夹。一些GUI工具会创建代表文件夹的空文件,而有些则不会。我不知道Typo3如何处理S3上的“文件夹”。

答案 1 :(得分:0)

对于那些寻求在使用S3时解决typo3中的文件列表问题的用户,您需要向所有文件夹添加ACL。

创建一个S3Client对象:

$s3 = new Aws\S3\S3Client([
        'region' => $region,
        'version' => 'latest',
        'credentials' => [
            'key' => $key,
            'secret' => $secret,
        ]
    ]);

并将ACL添加到您拥有的每个“文件夹”中:

$s3->putObject([
            'Bucket' => $bucket,
            'Key' => $folderToCreate,
            'Body' => '',
            'ACL' => 'public-read'
        ]);

您可以使用一个简单的.txt文件,其中包含您的文件夹列表

find -type d -printf "%P\n" > dirs.txt

或者,如果您喜欢过度设计,则可以使用

列出数组中的所有现有对象。
try {
        $results = $s3->getPaginator('ListObjects', [
            'Bucket' => $bucket
        ]);

        foreach ($results as $result) {
            foreach ($result['Contents'] as $object) {
                array_push($allObjects, $object['Key']);
            }
        }
    } catch (S3Exception $e) {
        echo $e->getMessage() . PHP_EOL;
    }

,您必须从以下位置进行:

删除文件(您只需要一个目录列表)。您可以为此使用pathinfo()

删除重复项

删除“。”和/或“ ..”值

您可能还需要为构成文件路径的子目录设置ACL(如果子目录中没有文件构成您的路径)

foreach ($allPaths as $longpath) {
        $explodedpath = explode('/', $longpath);

        $goodPathValue = '';

        foreach ($explodedpath as $segment) {

            if ($goodPathValue == '') {
                $goodPathValue = $segment;
            } else {

                // if it's not the first folder, we append the segment to it with a slash in between
                $goodPathValue .= "/" . $segment;
            }

            // at this point we either have first folder, or a part of the full path, which we enter in the array if it's unique
            if (!in_array($goodPathValue, $allPaths)) {
                array_push($allPaths, $goodPathValue);
            }
        }
    }

.txt或数组应为最佳效果的样子

downloads
downloads/en
downloads/en/user_upload
downloads/en/user_upload/Products
downloads/en/user_upload/Markets