[Django][AWS S3] botocore.exceptions.clienterror 调用 PutObject 操作时发生错误(拒绝访问)
[Django][AWS S3] botocore.exceptions.clienterror an error occurred (accessdenied) when calling the PutObject operation
我正在尝试将 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
出现错误:
You have requested to collect static files at the destination
location as specified in your settings.
This will overwrite existing files!
Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel: 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
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
所以,我编辑了存储桶策略:
{
"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)
是AWS S3访问问题。
在 S3 存储桶控制台中,我将存储桶的 public 访问权限编辑为 public。
注意:仅当您打算使文件 public 可用时才执行此操作,例如您正在使用它来为您的网站提供文件,例如图片、css 等每个人都需要访问。
设置AWS_DEFAULT_ACL = None
对我有用。看起来 boto 默认请求 public-read
ACL,所以除非你已经创建了你的桶 public 它不会工作。
默认情况下,当您创建新存储桶时,所有 public s3 对象的访问都被阻止(默认情况下已勾选)。也就是说,您不能通过任何 public api 或应用程序(如 django 应用程序)访问对象(读、写)。因此,如果您想访问特定存储桶中的 s3 对象,您应该将权限设置为 publicly 可访问(请参阅存储桶的权限部分)。为了进一步控制,您可以从 ACL 部分添加 ACL(访问控制列表)用户。
你可以参考这个link
这对我有用:
In my S3 bucket -> Permissions Tab -> click Block public access -> Edit -> untick Block all public access -> Save
和
In my AWS IAM settings -> Users Tab (under Access Management) -> <my-user> -> Add Permissions -> add AmazonS3FullAccess
这授予用户(由 AWS id 和 AWS 密码标识)访问权限以控制我的 s3 存储桶
设置AWS_S3_REGION_NAME='your-region' 例如:'us-east-2'
是访问控制列表(ACL)
Buckets -> Permission -> ACL -> Edit -> 勾选 Everyone(public access) List and Read for Objects and bucket ACL
如果有人仍然遇到这些问题,问题出在 AWS S£ 存储桶上,您可以通过在 s3 存储桶上启用 ACL 来解决问题。为此,
- 转到您的 S3 存储桶 > 权限选项卡
- 向下滚动到
Object Ownership
并点击编辑
- 将设置从禁用 ACL 更改为启用 ACL 并保存更改
我正在尝试将 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
出现错误:
You have requested to collect static files at the destination location as specified in your settings.
This will overwrite existing files! Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel: 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 raise error_class(parsed_response, operation_name) botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
所以,我编辑了存储桶策略:
{
"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)
是AWS S3访问问题。
在 S3 存储桶控制台中,我将存储桶的 public 访问权限编辑为 public。
注意:仅当您打算使文件 public 可用时才执行此操作,例如您正在使用它来为您的网站提供文件,例如图片、css 等每个人都需要访问。
设置AWS_DEFAULT_ACL = None
对我有用。看起来 boto 默认请求 public-read
ACL,所以除非你已经创建了你的桶 public 它不会工作。
默认情况下,当您创建新存储桶时,所有 public s3 对象的访问都被阻止(默认情况下已勾选)。也就是说,您不能通过任何 public api 或应用程序(如 django 应用程序)访问对象(读、写)。因此,如果您想访问特定存储桶中的 s3 对象,您应该将权限设置为 publicly 可访问(请参阅存储桶的权限部分)。为了进一步控制,您可以从 ACL 部分添加 ACL(访问控制列表)用户。
你可以参考这个link
这对我有用:
In my S3 bucket -> Permissions Tab -> click Block public access -> Edit -> untick Block all public access -> Save
和
In my AWS IAM settings -> Users Tab (under Access Management) -> <my-user> -> Add Permissions -> add AmazonS3FullAccess
这授予用户(由 AWS id 和 AWS 密码标识)访问权限以控制我的 s3 存储桶
设置AWS_S3_REGION_NAME='your-region' 例如:'us-east-2'
是访问控制列表(ACL) Buckets -> Permission -> ACL -> Edit -> 勾选 Everyone(public access) List and Read for Objects and bucket ACL
如果有人仍然遇到这些问题,问题出在 AWS S£ 存储桶上,您可以通过在 s3 存储桶上启用 ACL 来解决问题。为此,
- 转到您的 S3 存储桶 > 权限选项卡
- 向下滚动到
Object Ownership
并点击编辑 - 将设置从禁用 ACL 更改为启用 ACL 并保存更改