为什么我的Amazon S3密钥权限不生效?

4 投票
3 回答
2846 浏览
提问于 2025-04-17 09:07

我正在使用Python的一个库叫做boto,这个库可以让我连接到亚马逊的S3服务,创建存储桶和键(也就是文件)。因为我的键和值是动态生成的,所以我选择用代码来实现,而不是通过网页界面(用网页界面是可以的)。我现在的代码是这样的:

import boto
from boto.s3.connection import S3Connection
from boto.s3.key import Key

conn = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
bucket = conn.create_bucket(BUCKET_NAME)
bucket.configure_website('index.html', 'error.html')
bucket.set_acl('public-read')

for template in ['index.html', 'contact-us.html', 'cart.html', 'checkout.html']:
    k = Key(bucket)
    k.key = key
    k.set_acl('public-read')
    k.set_metadata('Content-Type', 'text/html')
    k.set_contents_from_string(get_page_contents(template))

我在这段代码中遇到了各种错误和问题。当我尝试更新已经存在的键时,我会把每个键的访问权限设置为public-read,但是在浏览器中查看文件时,仍然会出现403禁止访问的错误。

我还尝试删除所有的键,然后从头开始重新创建,但现在我遇到了NoSuchKey的异常。显然,键是不存在的,因为我正试图创建它。

我这样做是不是错了?有没有其他方法可以创建这些键,而不是更新它们?还有,我是不是遇到了某种竞争条件,导致权限没有生效?

3 个回答

2

我通过使用政策这个关键词参数,成功一次性设置了访问控制列表(ACL):

k.set_contents_from_stream(buff, policy='public-read')
4

我也遇到过这个问题。boto的 set_contents_from_string() 方法似乎会把文件的访问权限设置为私有,这样就会覆盖掉之前设置的任何访问权限。

所以如果你先用 set_acl('public-read') 设置了访问权限为“公开可读”,然后再用 set_contents_from_string(),那么之前的“公开可读”权限就会被覆盖掉。

11

我现在还不太明白上面的代码为什么不管用,但我发现了一种不同的(或者说是更新的?)创建键的写法。操作的顺序似乎也会有一些影响。下面是我找到的可以正常工作的写法:

conn = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
bucket = conn.create_bucket(store.domain_name)
bucket.set_acl('public-read')
bucket.configure_website('index.html', 'error.html')

for template in ['index.html', 'contact-us.html', 'cart.html', 'checkout.html']:
    k = bucket.new_key(template)
    k.set_metadata('Content-Type', 'text/html')
    k.set_contents_from_string(get_page_contents(template))
    k.set_acl('public-read') #doing this last seems to be important for some reason

撰写回答