通过使用AWS-SDK PHP生成的预签名帖子拒绝了AWS S3上传访问 [英] AWS S3 Upload Access Denied through Presigned post generated with AWS-SDK PHP

查看:98
本文介绍了通过使用AWS-SDK PHP生成的预签名帖子拒绝了AWS S3上传访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用AWS SDK PHP生成的带有预签名帖子将文件(用于测试的图像)上传到我的s3存储桶.首先我生成预签名的帖子,然后我用邮递员或通过简单的html表单手动使用给定的PostObjectV4数据创建请求.填满所有内容后,请求将导致访问被拒绝:-(..与客户端关联以生成PostObjectV4的用户在相应的存储段上具有允许的s3:PutObject策略.

i'm trying to upload a file (an image for my tests) to my s3 bucket with a pre-signed post generated with AWS SDK PHP. Firstable i generate the pre-signed post, then i manually create the request with given PostObjectV4 datas with Postman or via a simple html form... After filling everything, the request result in Access Denied :-(. The user associated with the client to generate the PostObjectV4 has Allowed s3:PutObject policy on the corresponding bucket.

我已经尝试过:

  • 将我的存储桶设置为公共写操作,它可以正常工作!这表明我存在许可/政策问题.不幸的是,我的存储桶不必公开...
  • 通过aws命令行上传文件,它也可以工作

预签名后生成的PHP代码(数据位于$ postObject中):

$assetAwsS3Key = $this->getAssetAwsS3Key($asset);

$options = [
    ['starts-with', '$key', 'myDir/'],
];

// Optional: configure expiration time string
$expires = '+24 hours';

// Set some defaults for form input fields
$formInputs = ['acl' => 'private'];

$postObject = new PostObjectV4(
    $this->buildAwsS3UserClient(),
    $this->awsBucketName,
    $formInputs,
    $options,
    $expires
);

// Get attributes to set on an HTML form, e.g., action, method, enctype
$formAttributes = $postObject->getFormAttributes();

// Get form input fields. This will include anything set as a form input in
// the constructor, the provided JSON policy, your AWS access key ID, and an
// auth signature.
$formInputs = $postObject->getFormInputs();

return ['formAttributes' => $formAttributes, 'formInputs' => $formInputs];

我的用户(用于生成客户端)策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::awsBucketName/*"
            ]
        }
    ]
}

我用于测试上传的简单HTML表单:

<form method="post" action="https://my-bucket.s3.eu-west-3.amazonaws.com" enctype="multipart/form-data">
        <input type="hidden" name="key" value="myKey/sources/myImg.jpg" /><br />
        <input type="file"   name="file" /> <br />
        <input type="hidden" name="X-Amz-Credential" value="MYUSERACCESSKEY/20190510/eu-west-3/s3/aws4_request" />
        <input type="hidden" name="X-Amz-Algorithm" value="AWS4-HMAC-SHA256" /> 
        <input type="hidden" name="X-Amz-Date" value="20190510T132109Z" />
        <input type="hidden" name="Policy" value='MYBASE64ENCODEDPOLICY' />
        <input type="hidden" name="X-Amz-Signature" value="MYSIGNATURE" />
        <input type="submit" name="submit"/>
    </form>

您是否有一个主意/线索,为什么在不允许进行存储桶的公共写访问时此上传失败?

Do you have an idea/clue why this upload fail while the bucket isn't public write-access allowed ?

非常感谢!

推荐答案

我摆脱了这个问题,我将分享自从我的第一篇博文以来在这里所做的更改,以使上载生效.请根据需要调整它.

I got rid of the problem, i'll share the changes i made here since my first post in order to get the upload to work. Please adapt it to your needs if necessary.

使用的AWS配置:-与第一条帖子相同的 in-line 策略(请确保您在资源密钥中设置的存储桶名称)-未附加任何政策的S3存储桶-S3存储桶已禁止所有公共访问

The AWS configuration used: - Same in-line policy attached to my user as in the first post(please be sure of the bucket name you set in the resource key) - S3 Bucket with no policy attached to it - S3 Bucket All Public Access Disabled

这是我用于创建postObject的最新php代码:

Here is my up to date php code for creating the postObject :

    $objectKey = $this->objectKeyGenerator->getObjectKey($object);

    $options = [
        ['bucket' => $this->getBucketName()],
        ['eq', '$key', $objectKey],
        ['acl' => 'private']
    ];

    // Optional: configure expiration time string
    $expires = '+2 hours';

    // Set some defaults for form input fields
    $formInputs = [
        'acl' => $acl,
        'key' => $objectKey
    ];

    $postObject = new PostObjectV4(
        $this->getS3Client(),
        $this->getBucketName(),
        $formInputs,
        $options,
        $expires
    );

    // Get attributes to set on an HTML form, e.g., action, method, enctype
    $formAttributes = $postObject->getFormAttributes();

    // Get form input fields. This will include anything set as a form input in
    // the constructor, the provided JSON policy, your AWS access key ID, and an
    // auth signature.
    $formInputs = $postObject->getFormInputs();

    return ['formAttributes' => $formAttributes, 'formInputs' => $formInputs];

与我的第一篇文章相比,postObject一代中发生了什么变化:

What changes in the postObject generation compared to my first post :

  • 我不再使用'starts-with'选项,而是手动生成对象密钥,这样上传的文件将仅需按生成的密钥进行上传(如果指定了另一个密钥,则由于密钥非相等),但我认为这不是导致错误的原因,而且我很确定它始终可以与"starts-with"选项一起使用.
  • 存储桶 acl 属性现在位于$ options数组中,作为适用于PHP的AWS开发工具包指南中提供的Create PostObjectV4示例代码(请参阅[ https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-presigned-post.html] ).
  • 在$ formInputs数组中,存在 key ,以便我可以在postObject中将其取回(因为提交的密钥必须是计算出的密钥).我认为这不是强制性的.
  • I did not use 'starts-with' option anymore and generate the object key manually so that the uploaded file will have to be uploaded only at the generated key (if another key is given it will fail because of the key non-equality), but i think this is was not what was leading to the error and i'm pretty sure it will always work with 'starts-with' option.
  • bucket and acl attributes are now in the $options array as the Create PostObjectV4 sample code given in the AWS SDK for PHP Developer Guide (see [https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-presigned-post.html]).
  • In the $formInputs array, key is present, so that i can get it back in the postObject (because the key submitted must be the one calculated). I think this is not mandatory.

我试图通过从$ option数组中删除 bucket acl 来重现该错误,并导致出现"403 Forbidden error",但出现一条消息,指出根据政策无效:额外输入字段:bucket",我发现这不是很明显...我没有对此错误进行更多调查.

I tried to reproduce the error by removing the bucket and acl from the $option array and this led to an '403 Forbidden error' but with a message stating 'Invalid according to Policy: Extra input fields: bucket' which i find not very obvious... I haven't investigate more on this error.

我还分享了我的html表单,该表单自第一篇文章发布以来就有所更改,输入字段的顺序已更改,并且由于该政策的要求添加了acl字段.

I'm also sharing my html form that changed a bit since first post, input fields order changed and acl field was added because required by the policy.

    <form method="post" action="https://my-bucket.s3.eu-west-3.amazonaws.com/" enctype="multipart/form-data">
    <input type="hidden" name="key" value="object/key.txt" /><br />
    <input type="hidden" name="acl" value="private"/>
    <input type="hidden" name="X-Amz-Credential" value="MYUSERACCESSKEY/20190510/eu-west-3/s3/aws4_request" />      
    <input type="hidden" name="X-Amz-Algorithm" value="AWS4-HMAC-SHA256" /> 
    <input type="hidden" name="X-Amz-Date" value="20200108T093921Z" />
    <input type="hidden" name="Policy" value='MYBASE64ENCODEDPOLICY' />
    <input type="hidden" name="X-Amz-Signature" value="MYSIGNATURE" />
    File: 
    <input type="file"   name="file" /> <br />
    <!-- The elements after this will be ignored -->
    <input type="submit" name="submit"/>

最后,在我的原始帖子中,我没有谈论我的s3存储桶 public-access policy 配置,我认为问题可能出在这里.

To conclude, in my original post i don't talk about my s3 bucket public-access and policy configuration and i think that the problem could have been here.

希望这会有所帮助,如有必要,随时询问详细信息.

Hope this helps, feel free to ask for details if necessary.

这篇关于通过使用AWS-SDK PHP生成的预签名帖子拒绝了AWS S3上传访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆