S3存储桶中WebP对象访问被拒绝问题求助
问题
为网站迁移至WebP图片格式,我通过以下Python代码批量将S3存储桶中的JPG图片转换为WebP格式并上传回存储桶:
my_path = 'bucket-name' AWS_ACCESS_KEY_ID = 'Some key' AWS_SECRET_ACCESS_KEY = 'some other key' s3 = boto3.resource('s3') my_bucket = s3.Bucket(my_path) s3_path = f'https://s3-eu-west-2.amazonaws.com/{my_path}/' s3client = boto3.client('s3') local_file = '/path to local file/local_image2.jpg' for my_bucket_object in my_bucket.objects.filter(Prefix='local/media/filer_public_thumbnails/'): if my_bucket_object.key[-4:] == '.jpg' and 'filer_public_thumbnails/' in my_bucket_object.key: try: key = my_bucket_object.key image = my_bucket.Object(key) img_data = image.get().get('Body').read() im = Image.open(BytesIO(img_data)) im.save(f'{local_file}.webp', format='webp') s3client.upload_file(f'{local_file}.webp', my_path, f'{key}.webp') except Exception as e: self.log(f'Error {e} for {my_bucket_object.key}') self.email_log()
本地生成的WebP图片正常,但尝试查看或获取S3存储桶中的WebP对象时提示Access Denied。我已关闭公开访问限制,且补充了以下存储桶策略:
{ "Sid": "VisualEditor20", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": [ "s3:PutObject", "s3:GetObjectAcl", "s3:GetObject", "s3:ListBucket", "s3:DeleteObject", "s3:PutObjectAcl" ], "Resource": [ "arn:aws:s3:::bucket-name/*", "arn:aws:s3:::bucket-name" ] }
请问该如何解决此访问被拒绝问题?
解决方案
1. 强制设置上传对象的公共读ACL
代码中使用s3client.upload_file上传时,默认会沿用存储桶的ACL配置,但可能因boto3默认设置或本地环境问题,导致WebP对象被设为私有。修改上传代码,显式指定公共读权限:
s3client.upload_file( f'{local_file}.webp', my_path, f'{key}.webp', ExtraArgs={'ACL': 'public-read'} )
上传后到S3控制台检查WebP对象的权限,确认非所有者用户是否拥有读取权限。
2. 检查存储桶策略的完整性与有效性
你提供的策略片段可能是完整策略的一部分,需确保整个存储桶策略是合法的JSON格式(无多余逗号、未闭合括号等语法错误)。同时排查是否存在Deny规则——AWS权限评估遵循"拒绝优先"原则,任何匹配的Deny规则都会直接阻止访问。
3. 验证对象路径与策略资源范围匹配
确认WebP对象的完整路径(如local/media/filer_public_thumbnails/xxx.jpg.webp)是否完全匹配策略中的arn:aws:s3:::bucket-name/*资源范围,避免因路径前缀不符导致策略不生效。
4. 排查IAM用户/角色权限限制
如果是通过特定IAM用户或角色访问WebP对象,需确保该身份拥有s3:GetObject权限,且没有被IAM策略中的Deny语句限制。即使存储桶策略允许公共访问,IAM层面的限制依然会生效。
5. 测试匿名访问并清除缓存
用浏览器匿名窗口打开WebP文件的URL测试,排除本地缓存的旧权限影响。同时确认URL的区域、桶名、对象路径拼写完全正确。
内容的提问来源于stack exchange,提问作者HenryM

