You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用boto3 create_presigned_post上传S3文件后访问报AccessDenied如何解决

问题根因

默认情况下S3存储桶和存储的对象都是私有权限,只有持有对应AWS凭证的身份才能访问。你直接复制S3原始对象URL访问属于匿名请求,没有权限自然会返回AccessDenied错误。

实现浏览器下载的可行方案
  • 方案1:生成下载专用的预签名URL (最推荐,适合非公开的敏感文件)
    该方案不需要修改存储桶的全局权限,只需要在文件上传成功后,为对应对象生成带签名的临时下载URL返回给前端即可,代码示例如下:
def create_presigned_download_url(bucket_name, object_name, expiration=3600):
    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
    return response

你可以在upload接口里,上传成功后调用这个函数,把返回的URL传给前端,用户点击这个URL就可以直接在浏览器下载/预览文件,URL的有效期可以通过expiration参数自定义。

  • 方案2:设置对象为公开可访问 (适合非敏感的公开资源)
    如果你的文件不需要权限控制,可以选择两种配置方式:
  1. 上传时指定对象ACL为公开读,修改你现有的create_presigned_post调用逻辑,传入fields参数指定acl:
result = create_presigned_post("bucket123", filename, fields={'acl': 'public-read'})

注意要提前在S3桶的权限设置中关闭「阻止所有公开访问」的相关配置,允许对象设置公开ACL。
2. 给S3桶配置全局公开读策略,适合桶内所有文件都需要公开访问的场景,桶策略示例如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::bucket123/*"
        }
    ]
}

注意:该方案会让桶内所有文件都可被匿名用户访问,存在数据泄露风险,请勿用来存储敏感文件。

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 16:48:00