【问题标题】:S3 Object upload to a private bucket using a pre-signed URL result in Access denied使用预签名 URL 将 S3 对象上传到私有存储桶导致访问被拒绝
【发布时间】:2021-07-05 15:10:54
【问题描述】:

我正在学习 AWS,并且我对 AWS 的了解有限,我是否正确地说,如果我制作预签名的 URL 以从存储桶上传和下载 - 设置为阻止所有公共访问,它应该可以工作吗?我通过 API 网关进行所有身份验证和检查,因此如果用户能够访问返回预签名 URL 以上传/下载的端点,那么他们就可以这样做。

如果我是正确的,那么当我尝试通过预签名的 URL 将图像上传到我的存储桶(阻止公共访问)时,我很困惑为什么会收到 Access denied 错误 - 它在以下情况下完美运行存储桶设置为公开?

创建预签名 URL 的我的 Lambda 函数:

const AWS = require('aws-sdk');
AWS.config.update({region: process.env.AWS_REGION});
const s3 = new AWS.S3()

// Main entry point
exports.handler = async (event) => {
    const result = await getUploadURL()
   // console.log('Result: ' result)
    return result;
}

const getUploadURL = async function(){
    const randomID = parseInt(Math.random()*10000000000)

    const s3Params = {
        Bucket: process.env.UploadBucket,
        Key: `${randomID}.jpg`,
        ContentType: 'image/jpeg',
        ACL: 'public-read'
    }

    console.log('getUploadURL: ', s3Params)
    return new Promise((resolve, reject) => {
        // Get signed URL
        resolve({
            "statusCode": 200,
            "isBase64Encoded": false
            "body": JSON.stringify({
                "uploadURL": s3.getSignedUrl('putObject', s3Params),
                "photoFilename": `${randomID}.jpg`
            })
        })
    });
}

我的 python 代码获取了预签名的 URL 并使用它来上传对象:

def upload_file_new(fileDir):
    presignedURL = requests.get('<URL>').json()['uploadURL']
    data = open(fileDir, 'rb').read()
    result = requests.put(presignedURL, data=data, headers={'Content-type': 'image/jpeg'})

我的 lambda 函数政策:

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

【问题讨论】:

  • 尝试删除标题
  • @jellycsc 没用,我在发帖之前试过了

标签: python node.js amazon-web-services amazon-s3 aws-lambda


【解决方案1】:

您的存储桶可能已打开Block all public access。因此,不能将对象的 ACL 设置为public-read。解决方法是你可以关闭Block all public access或者将public-read改为private

【讨论】:

  • 如何为我的存储桶保留“阻止所有公共访问”选项?使用签名的 url 来访问和上传对象到公开的存储桶没有意义吗?什么是“公开阅读”
  • @Nathan 如果您关闭了Block all public access,并不一定意味着您存储桶中的所有对象都会突然变为公共对象。相反,这意味着它允许您拥有一个存储桶策略或 ACL,授予对存储桶中 一些 对象的匿名访问权限。
  • @Nathan 你可以了解更多关于public-readhere的信息。
  • @Nathan 如果您还想让用户通过预签名 URL 访问对象,那么将 ACL 设置为 public-read 是没有意义的。你应该保留它private 以防止它被匿名访问。
  • 谢谢,我去看看。那么,您首选的使用预先签名 URL 的方式是什么?
猜你喜欢
  • 2020-10-09
  • 1970-01-01
  • 2019-12-04
  • 1970-01-01
  • 2019-02-03
  • 2020-02-18
  • 2016-03-18
  • 2021-02-21
  • 1970-01-01
相关资源
最近更新 更多