无S3桶全局权限时如何通过Boto3访问桶内指定文件
S3子路径权限下Boto3操作403问题解决方案
报错原因
Boto3默认的download_file方法会先触发HeadObject请求校验对象是否存在,同时你代码中S3对象键填写了多余的前导斜杠,二者共同触发了403权限报错。你被授予的仅为特定子路径的读写权限,不包含存储桶全局校验类接口的调用权限。
解决方案
方案1:使用get_object替代download_file(无需额外配置)
直接调用get_object接口拉取对象内容,不会提前触发额外的权限校验,同时修正对象键的前导斜杠即可正常运行,代码示例:
import boto3 client = boto3.client( 's3', aws_access_key_id = 'ACCESSKEY', aws_secret_access_key = 'SECRET', region_name = 'us-east-1' ) # 注意:S3对象键无需添加前导斜杠 s3_object_key = "FOLDER/PATH/FILENAME.json" response = client.get_object(Bucket="BUCKETNAME", Key=s3_object_key) # 写入本地文件 with open("LOCALFILENAME", "wb") as f: f.write(response['Body'].read())
上传操作同理,使用put_object替代upload_file即可避开校验。
方案2:Boto3中类似boto2 validate=False的替代实现
如果你习惯使用S3 Resource接口操作,可以直接构造Object对象,无需提前调用存储桶校验类接口,即可实现相同的跳过全局权限校验效果,代码示例:
import boto3 resource = boto3.resource( 's3', aws_access_key_id = 'ACCESSKEY', aws_secret_access_key = 'SECRET', region_name = 'us-east-1' ) # 直接构造对应路径的Object对象,不会触发存储桶级别的权限校验 s3_object = resource.Object("BUCKETNAME", "FOLDER/PATH/FILENAME.json") s3_object.download_file("LOCALFILENAME")
注意事项
- 所有S3对象键不要添加前导斜杠,否则会被识别为键名的一部分,导致对象不存在触发403
- 操作过程中不要调用
bucket.objects.all()、client.head_bucket()这类需要存储桶全局权限的接口
内容的提问来源于stack exchange,提问作者Michael Hayes
相关产品推荐
相关产品推荐

