Ошибка при удалении объектов AWS S3 из Django Web App

У меня возникает следующая ошибка, когда я пытаюсь удалить файлы S3 из моего Python/Django Webapp.

ClientError at /eq83/deletephoto
An error occurred (AccessDenied) when calling the DeleteObject operation: Access Denied

У меня нет проблем с просмотром или загрузкой файлов.

Некоторые подробности о разрешениях ведра

Все флажки block public access сняты.

Bucket policy пуст и говорит No policy to display.

В списке управления доступом (ACL) все флажки отмечены для bucket owner, а остальные не отмечены.

Это кросс-оригинальный обмен ресурсами (CORS)

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "POST",
            "PUT",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]

Некоторые подробности о моей заявке

Ниже приведена выдержка из моего файла settings.py. Я заблокировал секретный ключ и опустил TEMPLATES, MIDDLEWARE и некоторые INSTALLED_APPS


import os
import dotenv
dotenv.read_dotenv()

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'

DEBUG = True

ALLOWED_HOSTS = ["*"]


INSTALLED_APPS = [
'tracker.apps.TrackerConfig',
...
'storages'
]

WSGI_APPLICATION = 'tracker_django.wsgi.application'


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

STATIC_URL = '/static/'

STATICFILES_DIRS = [os.path.join(BASE_DIR,'tracker', 'static')]

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY', '')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_KEY', '')

AWS_STORAGE_BUCKET_NAME = 'tracker-django-files'

AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = "public-read"

AWS_QUERYSTRING_AUTH = False

Вот пример того, как я удаляю файлы в моем views.py.

def remove_eq_files(request, file_id):
    try:
        eq_file = EqFile.objects.get(pk=file_id)
        eq_id=eq_file.eq.id
    except KeyError:
        return render(request, "jobs/error.html", {"message": "No Selection"})
    except EqFile.DoesNotExist:
        return render(request, "jobs/error.html", {"message": "Invalid File Selection. Contact Admin"})
    #delete file in S3
    eq_file.eq_file.delete(save=False) 
    #delete file in django
    eq_file.delete() 
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

Наконец, вот фрагмент кода из файла models.py


class Eq(models.Model):
    name = models.CharField(max_length=128, blank=False)

def eq_file_path(instance, filename):
    try:
        eq=instance.eq
        path= "eq/"+eq.name +"_"+str(eq.pk)+"/eq_folder/"+filename
        return path

class EqFile(models.Model):
    eq_file=models.FileField(max_length=500, null=True, blank = True, upload_to = eq_file_path)
    file_url=models.URLField(max_length=500, null=True, blank=True)
    file_name = models.CharField(max_length=256, null=True, blank=True)
    eq= models.ForeignKey(Eq, null=True, on_delete=models.CASCADE, blank=True, related_name="eq_file")
    def filename(self):
        return os.path.basename(self.model_file.name)

Я попросил кого-то более опытного настроить s3 и помочь мне интегрировать его, и все работало хорошо более года, включая удаление объектов, я думаю, что последний раз я тестировал около 4 недель назад. Мне кажется необычным, что удаление больше не работает, и я подумал, что, возможно, Amazon что-то изменила в способе удаления объектов s3. Или, возможно, я невольно изменил какой-то код на стороне Python и все испортил.

(Пожалуйста, обратите внимание, что это программное обеспечение еще не используется клиентами, и я знаю, что эти настройки могут не подходить для развертывания. )

Любая помощь будет великолепно оценена!

Одним из решений этой проблемы, которое я в итоге реализовал, было создание пользователя IAM, предоставление ему прав на редактирование ведра, а затем добавление учетных данных IAM в program.

Настройте IAM

  1. откройте консоль AWS, используйте панель поиска, чтобы открыть 'IAM'
  2. .
  3. выберите 'Users' слева в разделе 'Access management' и создайте нового пользователя IAM. Важно: сохраните где-нибудь учетные данные безопасности (ключ доступа и секретный ключ) и сохраните ARN пользователя
  4. .
  5. нажмите '+ add inline policy' на справа и создайте новую политику с кодом ниже, за исключением замены BUCKETS!!! на имя вашего ведра.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:ListBucketVersions",
                "s3:GetBucketLocation",
                "s3:Get*",
                "s3:Put*",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKETS!!!",
                "arn:aws:s3:::BUCKETS!!!/*"
            ]
        }
    ]
}

Предоставьте IAM права на редактирование ведра

  1. В AWS откройте S3 (через панель поиска или меню) и нажмите Buckets слева
  2. .
  3. щелкните ведро, которое вы хотите изменить, и перейдите на вкладку 'Permissions'
  4. .
  5. прокрутите вниз до 'Bucket policy', нажмите Edit, и вставьте код ниже, за исключением замены USERARN!!! на User ARN, который вы сохранили ранее в IAM Management Console и замены BUCKETS!!! на имя вашего ведра.
{
    "Version": "2012-10-17",
    "Id": "Policy1488494182833",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "USERARN!!!"
            },
            "Action": [
                "s3:ListBucket",
                "s3:ListBucketVersions",
                "s3:GetBucketLocation",
                "s3:Get*",
                "s3:Put*",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKETS!!!",
                "arn:aws:s3:::BUCKETS!!!/*"
            ]
        }
    ]
}

Теперь любой человек с учетными данными для входа в IAM может манипулировать ведром.

Добавьте учетные данные IAM в программу.

Поскольку мой проект является проектом Django, я использую boto3, и я ввел учетные данные в settings.py, просто добавив данные ниже, за исключением замены AK!!! на ключ доступа, который вы сохранили ранее, и SK!!! на секретный ключ доступа, который вы сохранили ранее.

AWS_ACCESS_KEY_ID = 'AK!!!'
AWS_SECRET_ACCESS_KEY = 'SK!!!'

Я не знаю, как вы это сделаете, если не используете Django framework.

Спасибо за подсказку luk2302 о том, как настроить пользователя IAM.

Вернуться на верх