通过使用 AWS-SDK PHP 生成的预签名帖子拒绝 AWS S3 上传访问

2024-05-01

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

我已经尝试过:

  • 将我的存储桶设置为公共写入,并且它有效!这表明我存在权限/政策问题...不幸的是我的存储桶不必公开...
  • 通过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>

您知道为什么此上传失败而存储桶不允许公共写入访问吗?

提前谢谢了 !


我解决了这个问题,我将分享自第一篇文章以来我在这里所做的更改,以便上传工作。如有必要,请根据您的需要进行调整。

使用的AWS配置: - 相同的in-line如第一篇文章中附加到我的用户的策略(请确保您在资源密钥中设置的存储桶名称) - 没有附加策略的 S3 存储桶 - S3 Bucket所有公共访问均已禁用

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

    $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 生成有何变化:

  • 我不再使用“starts-with”选项并手动生成对象密钥,以便上传的文件只能在生成的密钥上上传(如果给出另一个密钥,则会因为密钥不相等而失败),但我认为这不是导致错误的原因,而且我很确定它将始终与“starts-with”选项一起使用。
  • bucket and acl属性现在位于 $options 数组中,作为 AWS SDK for PHP 开发人员指南中提供的 Create PostObjectV4 示例代码(请参阅 [https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-presigned-post.html] https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-presigned-post.html%5D).
  • 在 $formInputs 数组中,key存在,以便我可以将其返回到 postObject 中(因为提交的密钥必须是计算得出的密钥)。我认为这不是强制性的。

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

我还分享了我的 html 表单,自第一篇文章以来,该表单发生了一些变化,输入字段顺序发生了变化,并且根据策略的要求添加了 acl 字段。

    <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 存储桶公共访问 and policy配置,我认为问题可能就在这里。

希望这对您有所帮助,如有需要,请随时询问详细信息。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过使用 AWS-SDK PHP 生成的预签名帖子拒绝 AWS S3 上传访问 的相关文章

  • 显示表中的记录

    我的第一个 PHP 项目遇到了一些麻烦 我试图从 MySQL 数据库 有 3 条记录 获取数据并将其显示在表格中 问题是它似乎只显示记录 2 和 3 它跳过了第 1 条记录 请参阅我的代码并在下面显示 if mysqli connect e
  • 为什么我不能在 TCPDF 表中使用 č,ć,đ 图表?

    我正在为我的网站构建一个 tcpdf 文件 该 tcpdf 文件中有一个包含一些数据的表格 但我无法使该章程正常工作 对于编码 我使用 windows 1250 宪章女巫不起作用 我已经尝试过 utf 8 但仍然没有得到这个章程 tcpdf
  • Smarty输出空白页

    已解决 模板文件错误 我有这样的 Smarty 设置 require once smarty Smarty class php smarty new Smarty smarty gt compile dir compile dir smar
  • 如何复制 ArrayIterator 以保留其当前迭代位置?

    因为这似乎是我必须做的才能达到这种效果 arr a gt first b gt second iter new ArrayIterator arr Do a bunch of iterations iter gt next new iter
  • WooCommerce 使用 AJAX 设置购物车数量?

    我已经为此绞尽脑汁好几天了 需要一些指导 我正在为 WooCommerce 网站完全从头开始制作自定义主题 现在我正在尝试让购物车功能正常工作 我一直试图使用按钮 来更新购物车中产品的数量 对我来说问题似乎是WC 我在functions p
  • PHP 绑定“bigint”数据类型(MySQLi 准备好的语句)

    studentId 57004542323382 companyOfferId 7 sql INSERT INTO studentPlacement companyOfferId studentId VALUES if stmt db gt
  • .htaccess 异常导致主目录出现问题

    这是我的目录结构 localhost or livehost app bootstrap public vendor code demo 这是我的 htaccess
  • 当sql连接中存在两个同名列时,如何从一个表列中获取值

    当我连接两个具有相同名称列的表时 我目前面临着尝试获取值的问题 例如 table1 date和table2 date 每个表中的日期不同 我将如何获取 日期 本例中的表1 我目前正在跑步 while row mysqliquery gt f
  • 负载平衡集群中的 PHP 会话 - 如何?

    好的 我得到了这个完全罕见的负载平衡 PHP 网站的独特场景 令人遗憾的是 它过去没有进行负载平衡 现在我们开始遇到问题 目前唯一的问题是 PHP 会话 当然 一开始没有人想到这个问题 因此 PHP 会话配置保留为默认值 因此 两台服务器都
  • 第三个下拉菜单不从数据库填充

    我有以下 Index php
  • 为什么验证不起作用并跳转到另一个页面?

    我写了一个customer display php来验证数据 到目前为止只有名字 但无论名字字段是否为空 网页都会跳转到customer search php并且没有更改数据库中的信息 为什么
  • 如何在类似 MVC 的页面中加载基于漂亮 URL 的类?

    我想请教一些关于如何解决这个问题的提示 我正在尝试构建自己的 MVC 网站 我了解了 URL 的基础知识 http example com blog cosplay cosplayer expo today 博客 gt 控制器cosplay
  • PHP Solr PECL 扩展安装

    我已经使用命令安装了 pecl solr pecl install solr 和梨使用 wget http pear php net go pear phar php go pear phar 重启Apache后 我仍然收到错误 Fatal
  • 如何在 yii2 中使用两个不同的模型登录或切换身份类别?

    我想允许用户从两个不同的模型登录 配置文件 user gt identityClass gt app models User one more class here enableAutoLogin gt false authTimeout
  • fgetcsv 在特定行打开?

    有没有办法使用 fgetcsv 在特定行上打开 我有一个非常大的 csv 想通过 ajax 一次运行大约 100 行 我可以轻松停止 while 循环 但如何在特定行上打开 或者这是不可能的 从第 100 行开始读取没有简单的方法 但您可以
  • 检查条件并通过 Zend 中的 Regex 识别 url 中的模式

    我正在实现 Zend Regex 路由 并且必须对 url 执行多次检查 例如 如果这是我的网址 http localhost application public index php module controller action 这是
  • 从数据库填充复选框

    我有两个表 第一个由与名称关联的 id 组成 1 汽车 2 火车 3 普通 ETC 第二个表由两个字段 user id 和第一个表中的 id 组成 例如 1 1 2 1 3 当用户转到该页面时 我试图重新填充选定的复选框 首先 您查询数据库
  • 如何在 Zend Framework 3 中注册自定义表单视图助手

    我正在将继承的 Zend Framework 2 应用程序迁移到 Zend Framework 3 并且在注册自定义表单视图助手时遇到了一些困难 这些助手在应用程序使用版本 2 时起作用 主要用于添加标签属性以实现可访问性 例如 这是一个自
  • 检查 $_POST 数据

    我正在对表单进行一些垃圾邮件检查 下面的代码在我的本地主机上正常工作 如果为 true 则重定向到 google com 但是 当它在生产服务器上时却不起作用 执行脚本的其余部分并且不重定向到 Google com if POST SERV
  • 一种无需 JavaScript 即可在 PHP 中确定浏览器宽度的方法?

    首先有吗 或者我必须使用javascript 我希望能够更改使用的 CSS 因此 frex 我可以为移动设备或其他设备加载较小的字体 不幸的是 仅使用 PHP 无法检测用户分辨率 如果您使用 Javascript 则可以在 cookie 中

随机推荐