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

Posted

技术标签:

【中文标题】[Django][AWS S3] botocore.exceptions.clienterror 调用 PutObject 操作时发生错误(访问被拒绝)【英文标题】:[Django][AWS S3] botocore.exceptions.clienterror an error occurred (accessdenied) when calling the PutObject operation 【发布时间】:2019-07-14 07:11:38 【问题描述】:

我正在尝试将 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'

IAM 用户是使用 AmazonS3FullAccess 创建的。 但是当我进入时:

python manage.py collectstatic

发生错误:

您已请求在目的地收集静态文件 设置中指定的位置。

这将覆盖现有文件! 您确定要这样做吗?

输入“yes”继续,或输入“no”取消:yes 回溯(最近一次通话最后): 文件“manage.py”,第 22 行,在 execute_from_command_line(sys.argv) 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/core/management/init.py”, 第 381 行,在 execute_from_command_line 实用程序.execute() 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/core/management/init.py”, 第 375 行,执行中 self.fetch_command(子命令).run_from_argv(self.argv) 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/core/management/base.py”, 第 316 行,在 run_from_argv self.execute(*args, **cmd_options) 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/core/management/base.py”, 第 353 行,执行中 输出 = self.handle(*args, **options) 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py”, 第 188 行,在句柄中 收集 = self.collect() 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py”, 第 114 行,收集中 处理程序(路径,前缀路径,存储) 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py”, 第 353 行,在 copy_file 中 self.storage.save(prefixed_pa​​th, source_file) 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/core/files/storage.py”, 第 49 行,保存 返回self._save(名称,内容) 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/storages/backends/s3boto3.py”, 第 506 行,在 _save self._save_content(obj,内容,参数=参数) 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/storages/backends/s3boto3.py”, 第 521 行,在 _save_content obj.upload_fileobj(内容,ExtraArgs=put_parameters) 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/boto3/s3/inject.py”, 第 621 行,在 object_upload_fileobj 中 ExtraArgs=ExtraArgs,回调=回调,配置=配置) 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/boto3/s3/inject.py”, 第 539 行,在 upload_fileobj 中 返回future.result() 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/s3transfer/futures.py”, 第 106 行,结果 返回 self._coordinator.result() 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/s3transfer/futures.py”, 第 265 行,结果 提高self._exception 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/s3transfer/tasks.py”, 第 126 行,在 调用 返回 self._execute_main(kwargs) 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/s3transfer/tasks.py”, 第 150 行,在 _execute_main return_value = self._main(**kwargs) 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/s3transfer/upload.py”, 第 692 行,在 _main client.put_object(Bucket=bucket, Key=key, Body=body, **extra_args) 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/botocore/client.py”, 第 357 行,在 _api_call 中 return self._make_api_call(operation_name, kwargs) 文件“/home/seokchan/server/mdocker/lib/python3.5/site-packages/botocore/client.py”, 第 661 行,在 _make_api_call raise error_class(parsed_response, operation_name) botocore.exceptions.ClientError:调用PutObject操作时发生错误(AccessDenied):访问被拒绝

所以,我编辑了存储桶策略:


    "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)

【问题讨论】:

【参考方案1】:

这是 AWS S3 访问问题。

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

注意:仅当您打算公开文件时才这样做,例如您使用它来为您的网站提供文件,例如图像、css 等每个人都需要访问的东西。

【讨论】:

您能否详细说明.. 我也面临类似的问题。 这样做有什么潜在的安全问题? @virus on Permissions 标签 -> 点击 Block public access -> Edit -> 取消勾选 Block all public access - > 保存【参考方案2】:

设置AWS_DEFAULT_ACL = None 对我有用。默认情况下,它看起来像 boto 请求 public-read ACL,因此除非您将存储桶公开,否则它将无法工作。

【讨论】:

【参考方案3】:

这对我有用:

In my S3 bucket -&gt; Permissions Tab -&gt; click Block public access -&gt; Edit -&gt; untick Block all public access -&gt; Save

In my AWS IAM settings -&gt; Users Tab (under Access Management) -&gt; &lt;my-user&gt; -&gt; Add Permissions -&gt; add AmazonS3FullAccess

这授予用户(由 AWS id 和 AWS 秘密标识)访问控制我的 s3 存储桶的权限

【讨论】:

【参考方案4】:

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

你可以参考这个link

【讨论】:

【参考方案5】:

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

【讨论】:

以上是关于[Django][AWS S3] botocore.exceptions.clienterror 调用 PutObject 操作时发生错误(访问被拒绝)的主要内容,如果未能解决你的问题,请参考以下文章

AWS Elastic Beanstalk 使用 CLI 部署时出现 Botocore 错误

botocore.exceptions.ProfileNotFound 当代码在AWS弹性beantalk上运行时,但在本地没问题

aws、django、unicorn 和 s3 - 那我需要 nginx 吗?

使用 AWS S3 for django 在 heroku 上提供静态文件?

heroku 上的 Django 和 imagekit 保存到 AWS S3 非常慢

尝试访问管理字体文件时,Django 在 AWS S3 中托管静态文件导致 CORS 错误