【问题标题】:S3 File Access Denied when uploaded with pre-signed url boto3 call create_presigned_post()使用预签名 url boto3 调用 create_presigned_post() 上传时 S3 文件访问被拒绝
【发布时间】:2021-12-11 13:03:29
【问题描述】:

我有一个烧瓶应用程序,它生成一个到 S3 的预签名 URL 并将文件上传到存储桶中。 代码:

def create_presigned_post(bucket_name, object_name,
                          fields=None, conditions=None, expiration=3600):
    """Generate a presigned URL S3 POST request to upload a file

    :param bucket_name: string
    :param object_name: string
    :param fields: Dictionary of prefilled form fields
    :param conditions: List of conditions to include in the policy
    :param expiration: Time in seconds for the presigned URL to remain valid
    :return: Dictionary with the following keys:
        url: URL to post to
        fields: Dictionary of form fields and values to submit with the POST
    :return: None if error.
    """

    # Generate a presigned S3 POST URL
    s3_client = boto3.client('s3')
    try:
        response = s3_client.generate_presigned_post(bucket_name,
                                                     object_name,
                                                     Fields=fields,
                                                     Conditions=conditions,
                                                     ExpiresIn=expiration)
    except ClientError as e:
        logging.error(e)
        return None

    # The response contains the presigned URL and required fields
    return response
@app.route('/upload',methods=['post'])
def upload():
    if request.method == 'POST':
        diag_file = request.files['file']
        if diag_file:
                filename = secure_filename(diag_file.filename)
                diag_file.save(filename)
                result = create_presigned_post("bucket123", filename)
                # How another Python program can use the presigned URL to upload a file
                with open(filename, 'rb') as f:
                    files = {'file': (filename, f)}
                    http_response = requests.post(result['url'], data=result['fields'], files=files)
                # If successful, returns HTTP status code 204
                print(result['url'])
                print(http_response.status_code)
                logging.info(f'File upload HTTP status code: {http_response.status_code}')
                # s3.upload_file(
                #     Bucket = BUCKET_NAME,
                #     Filename=filename,
                #     Key = filename
                # )
                msg = "Diag file Uploaded!"

    return render_template("file_upload_to_s3.html",msg =msg)

文件上传正常,没有错误。

当我通过复制 S3 URL 并将其粘贴到同一浏览器中的另一个选项卡中访问文件时,我得到:

<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>CQNCGDS4YKCPDWQ6</RequestId>
<HostId>
LsJI1jBMUCeQpL4qjfqipmvYeCJ5TaS3ZoBwbmXMbbklWo5stWMdVtGI50Ib+XDciHerIm5AADw=
</HostId>
</Error>

如何通过浏览器从 S3 下载此文件?

【问题讨论】:

标签: python amazon-s3 boto3 access-denied pre-signed-url


【解决方案1】:

url bucket123.s3.us-west-2.amazonaws.com/test.tgz 仅在对象为 public 时才有效。这需要更改其 ACL 或设置存储桶策略。

如果您不想公开,则必须创建 S3 预签名 URL。所以基本上,你上次尝试做的是,但这次是 GET,而不是上传对象。

对于boto3,代码为here:

def create_presigned_url(bucket_name, object_name, expiration=3600):
    """Generate a presigned URL to share an S3 object

    :param bucket_name: string
    :param object_name: string
    :param expiration: Time in seconds for the presigned URL to remain valid
    :return: Presigned URL as string. If error, returns None.
    """

    # Generate a presigned URL for the S3 object
    s3_client = boto3.client('s3')
    try:
        response = s3_client.generate_presigned_url('get_object',
                                                    Params={'Bucket': bucket_name,
                                                            'Key': object_name},
                                                    ExpiresIn=expiration)
    except ClientError as e:
        logging.error(e)
        return None

    # The response contains the presigned URL
    return response

【讨论】:

    猜你喜欢
    • 2016-03-18
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 2022-01-28
    • 1970-01-01
    • 1970-01-01
    • 2019-09-18
    • 2017-04-11
    相关资源
    最近更新 更多