[Django][AWS S3] botocore.exceptions.clienterror在调用PutObject操作时发生访问被拒绝的错误(accessdenied)。

26
我正在尝试将Django项目连接到AWS S3。
settings.py包含以下内容:
AWS_ACCESS_KEY_ID = #ID
AWS_SECRET_ACCESS_KEY = #Key
AWS_STORAGE_BUCKET_NAME = #Bucket
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
}
AWS_LOCATION = 'static'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'backend/static'),
]
STATIC_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

已创建具有AmazonS3FullAccess的IAM用户。但是当我输入:

python manage.py collectstatic

出现错误:

您已经要求按照设置中指定的目标位置收集静态文件。

这将覆盖现有的文件! 你确定要这么做吗?

输入 'yes' 继续,或者输入 'no' 取消:yes Traceback (most recent call last): File "manage.py", line 22, in execute_from_command_line(sys.argv) File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/core/management/init.py", line 381, in execute_from_command_line utility.execute() File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/core/management/init.py", line 375, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/core/management/base.py", line 316, in run_from_argv self.execute(*args, **cmd_options) File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/core/management/base.py", line 353, in execute output = self.handle(*args, **options) File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 188, in handle collected = self.collect() File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 114, in collect handler(path, prefixed_path, storage) File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 353, in copy_file self.storage.save(prefixed_path, source_file) File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/core/files/storage.py", line 49, in save return self._save(name, content) File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/storages/backends/s3boto3.py", line 506, in _save self._save_content(obj, content, parameters=parameters) File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/storages/backends/s3boto3.py", line 521, in _save_content obj.upload_fileobj(content, ExtraArgs=put_parameters) File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/boto3/s3/inject.py", line 621, in object_upload_fileobj ExtraArgs=ExtraArgs, Callback=Callback, Config=Config) File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/boto3/s3/inject.py", line 539, in upload_fileobj return future.result() File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/s3transfer/futures.py", line 106, in result return self._coordinator.result() File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/s3transfer/futures.py", line 265, in result raise self._exception File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/s3transfer/tasks.py", line 126, in call return self._execute_main(kwargs) File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/s3transfer/tasks.py", line 150, in _execute_main return_value = self._main(**kwargs) File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/s3transfer/upload.py", line 692, in _main client.put_object(Bucket=bucket, Key=key, Body=body, **extra_args) File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/botocore/client.py", line 357, in _api_call return self._make_api_call(operation_name, kwargs) File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/botocore/client.py", line 661, in _make_api_call

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Allow All",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::<bucket name>/*"
        }
    ]
}

但是错误仍然发生。 我该如何解决这个错误?

我正在遵循的教程在这一步骤中没有显示任何错误。(https://simpleisbetterthancomplex.com/tutorial/2017/08/01/how-to-setup-amazon-s3-in-a-django-project.html

9个回答

23

设置AWS_DEFAULT_ACL = None对我起了作用。看起来boto默认请求public-read ACL,所以除非您将存储桶公开,否则它不会起作用。


谢谢 @madeofair! 我的问题出在ansible上,导致我找到了https://github.com/ansible/ansible/issues/48050,所以如果有人在ansible中遇到这个问题,解决方法是添加`permission: []`。 - undefined

16

这是AWS S3访问问题。

在S3存储桶控制台中,我将存储桶的公共访问权限更改为公共。

NB:只有在您打算公开文件时才应执行此操作。例如,如果您要用它来为您的网站提供文件服务,如图片、css等,每个人都需要访问。


1
请您详细说明一下,我遇到了类似的问题。 - Gaurav Pant
1
通过这样做,可能会存在哪些潜在的安全问题? - Jarad
1
权限 选项卡上点击 @virus -> 点击 阻止公共访问 -> 编辑 -> 取消勾选 阻止所有公共访问 -> 保存 - suhailvs

10
如果仍然遇到这些问题,问题出在AWS S3存储桶上,你可以通过在S3存储桶上启用ACL来解决。操作步骤如下:
  1. 进入S3存储桶>权限选项卡
  2. 向下滚动到对象所有权并点击编辑
  3. 将设置从ACL禁用更改为ACL启用并保存更改

这非常有用,因为上面的所有步骤都已经执行了,但问题仍然存在,直到修改了这个设置。谢谢。 - mrj

6
这对我有用:
在我的S3存储桶中->权限选项卡->点击“阻止公共访问”->编辑->取消勾选“阻止所有公共访问”->保存。
并且
在我的AWS IAM设置中->用户选项卡(访问管理下)->->添加权限->添加AmazonS3FullAccess。
这样可以授予用户(由AWS ID和AWS秘钥标识)访问和控制我的S3存储桶的权限。

1
如果您仍然遇到这些困难,问题可能出在 AWS S3 存储桶上。您可以通过在 S3 存储桶上启用访问控制列表 (ACL) 来解决问题。按照以下步骤进行必要的更改:
  1. 导航到您的 S3 存储桶并单击“权限”选项卡。
  2. 向下滚动到标记为“对象所有权”的部分,并选择“编辑”选项。
  3. 将设置从“ACL 禁用”修改为“ACL 启用”,并保存更改。

1
默认情况下,创建新存储桶时,所有S3对象的公共访问都被阻止(默认为选中)。也就是说,您不能通过任何公共API或应用程序(如Django应用程序)访问对象(读取、写入)。因此,如果您想访问特定存储桶中的S3对象,您应该将权限设置为公开访问(请参阅存储桶的权限部分)。为了进一步控制,您可以从ACL部分添加ACL(访问控制列表)用户。
您可以参考此链接

1
这是访问控制列表(ACL)相关的内容。 操作步骤为:Buckets(存储桶) -> Permission(权限) -> ACL(访问控制列表) -> Edit(编辑) -> 选中 Everyone(公共访问)列表并勾选读取对象和存储桶ACL。 以下是图片示例:enter image description here

0
对我来说,问题是错误的环境变量。
# settings file
AWS_S3_ACCESS_KEY_ID = os.environ["AWS_S3_ACCESS_KEY_ID"]
AWS_S3_SECRET_ACCESS_KEY = os.environ["AWS_S3_SECRET_ACCESS_KEY"]

AWS_S3_ACCESS_KEY_ID="random-key-id"
AWS_S3_SECRET_ACCESS_KEY="random-access-key"

在我移除了双引号之后,我再次运行了命令。现在它可以正常工作了。


-2

设置 AWS_S3_REGION_NAME='your-region',例如:'us-east-2'


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接