AWS S3/boto3使用预签名URL上传文件遇AccessDenied问题
问题分析与解决办法
核心错误原因:操作类型不匹配
你用get_object生成的预签名URL仅支持GET下载请求,但curl的--upload-file会发送PUT上传请求,两者操作类型不匹配,直接导致AccessDenied错误。这是最关键的问题,先修正这个。
修正步骤
1. 生成对应上传操作的预签名URL
把代码中的get_object替换为put_object,生成用于PUT上传的预签名URL:
s3_client = boto3.client('s3', endpoint_url=AWS_ENDPOINT) presigned_url = s3_client.generate_presigned_url('put_object', Params={'Bucket': "my-bucket", 'Key':"my-key"}, ExpiresIn=expiration)
2. 权限配置要求
- 生成预签名URL的IAM实体权限:执行代码的IAM用户/角色必须拥有
s3:PutObject权限,权限策略需要包含目标桶和对象Key的访问权限,示例策略片段:{ "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::my-bucket/my-key" } - 桶权限策略:如果桶配置了Bucket Policy,需要确保该策略不阻止IAM实体的
s3:PutObject操作。不需要给桶设置公共写权限,预签名URL本身就是基于IAM权限的临时授权,只要IAM权限足够即可。
额外排查点
- 确认生成预签名URL时使用的AWS凭证(access key/secret key)属于拥有对应权限的IAM实体。
- 检查endpoint_url是否正确,尤其是使用S3兼容存储(如MinIO、阿里云OSS等)时,端点地址不能出错。
- 如果桶开启了版本控制,无需额外配置,但要确保上传的Key没有冲突或特殊字符问题。
内容的提问来源于stack exchange,提问作者user1187968
相关产品推荐
相关产品推荐

