boto.exception.S3ResponseError: S3ResponseError: 403 Interdit

J’essaie de faire django télécharger des fichiers statiques sur S3, mais je reçois une erreur 403, et je ne sais pas trop pourquoi.

Full Stacktrace:

Traceback (most recent call last): File "manage.py", line 14, in  execute_manager(settings) File "/home/levi/Projects/DoneBox/.virtualenv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 438, in execute_manager utility.execute() File "/home/levi/Projects/DoneBox/.virtualenv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 379, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/home/levi/Projects/DoneBox/.virtualenv/local/lib/python2.7/site-packages/django/core/management/base.py", line 191, in run_from_argv self.execute(*args, **options.__dict__) File "/home/levi/Projects/DoneBox/.virtualenv/local/lib/python2.7/site-packages/django/core/management/base.py", line 220, in execute output = self.handle(*args, **options) File "/home/levi/Projects/DoneBox/.virtualenv/local/lib/python2.7/site-packages/django/core/management/base.py", line 351, in handle return self.handle_noargs(**options) File "/home/levi/Projects/DoneBox/.virtualenv/local/lib/python2.7/site-packages/django/consortingb/staticfiles/management/commands/collectstatic.py", line 89, in handle_noargs self.copy_file(path, prefixed_path, storage, **options) File "/home/levi/Projects/DoneBox/.virtualenv/local/lib/python2.7/site-packages/django/consortingb/staticfiles/management/commands/collectstatic.py", line 184, in copy_file if not self.delete_file(path, prefixed_path, source_storage, **options): File "/home/levi/Projects/DoneBox/.virtualenv/local/lib/python2.7/site-packages/django/consortingb/staticfiles/management/commands/collectstatic.py", line 115, in delete_file if self.storage.exists(prefixed_path): File "/home/levi/Projects/DoneBox/.virtualenv/local/lib/python2.7/site-packages/storages/backends/s3boto.py", line 209, in exists return k.exists() File "/home/levi/Projects/DoneBox/.virtualenv/local/lib/python2.7/site-packages/boto/s3/key.py", line 391, in exists return bool(self.bucket.lookup(self.name)) File "/home/levi/Projects/DoneBox/.virtualenv/local/lib/python2.7/site-packages/boto/s3/bucket.py", line 143, in lookup return self.get_key(key_name, headers=headers) File "/home/levi/Projects/DoneBox/.virtualenv/local/lib/python2.7/site-packages/boto/s3/bucket.py", line 208, in get_key response.status, response.reason, '') boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden 

Contenu de settings.py:

 import os DIRNAME = os.path.dirname(__file__) # Django settings for DoneBox project. DEBUG = True TEMPLATE_DEBUG = DEBUG ADMINS = ( # ('Your Name', 'your_email@example.com'), ) MANAGERS = ADMINS DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 'NAME': os.path.join(DIRNAME, "box.sqlite"), # Or path to database file if using sqlite3. 'USER': '', # Not used with sqlite3. 'PASSWORD': '', # Not used with sqlite3. 'HOST': '', # Set to empty ssortingng for localhost. Not used with sqlite3. 'PORT': '', # Set to empty ssortingng for default. Not used with sqlite3. } } # Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. # On Unix systems, a value of None will cause Django to use the same # timezone as the operating system. # If running in a Windows environment this must be set to the same as your # system time zone. TIME_ZONE = 'America/Denver' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'en-us' SITE_ID = 1 # If you set this to False, Django will make some optimizations so as not # to load the internationalization machinery. USE_I18N = True # If you set this to False, Django will not format dates, numbers and # calendars according to the current locale USE_L10N = True # Absolute filesystem path to the directory that will hold user-uploaded files. # Example: "/home/media/media.lawrence.com/media/" MEDIA_ROOT = '' # URL that handles the media served from MEDIA_ROOT. Make sure to use a # trailing slash. # Examples: "http://media.lawrence.com/media/", "http://example.com/media/" MEDIA_URL = "d1eyn4cjl5vzx0.cloudfront.net" # Absolute path to the directory static files should be collected to. # Don't put anything in this directory yourself; store your static files # in apps' "static/" subdirectories and in STATICFILES_DIRS. # Example: "/home/media/media.lawrence.com/static/" STATIC_ROOT = os.path.join(DIRNAME, "static") # URL prefix for static files. # Example: "http://media.lawrence.com/static/" STATIC_URL = "d280kzug7l5rug.cloudfront.net" # URL prefix for admin static files -- CSS, JavaScript and images. # Make sure to use a trailing slash. # Examples: "http://foo.com/static/admin/", "/static/admin/". ADMIN_MEDIA_PREFIX = '/static/admin/' # Additional locations of static files STATICFILES_DIRS = ( # Put ssortingngs here, like "/home/html/static" or "C:/www/django/static". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. os.path.join(DIRNAME, "main", "static"), ) # List of finder classes that know how to find static files in # various locations. STATICFILES_FINDERS = ( 'django.consortingb.staticfiles.finders.FileSystemFinder', 'django.consortingb.staticfiles.finders.AppDirectoriesFinder', 'django.consortingb.staticfiles.finders.DefaultStorageFinder', ) # Make this unique, and don't share it with anybody. SECRET_KEY = '' # List of callables that know how to import templates from various sources. TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', 'django.template.loaders.eggs.Loader', ) MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.consortingb.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.consortingb.auth.middleware.AuthenticationMiddleware', 'django.consortingb.messages.middleware.MessageMiddleware', ) ROOT_URLCONF = 'DoneBox.urls' TEMPLATE_DIRS = ( # Put ssortingngs here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. os.path.join(DIRNAME, "main", "templates"), os.path.join(DIRNAME, "templates"), os.path.join(DIRNAME, "basic", "blog", "templates"), ) INSTALLED_APPS = ( 'django.consortingb.auth', 'django.consortingb.contenttypes', 'django.consortingb.sessions', 'django.consortingb.sites', 'django.consortingb.messages', 'django.consortingb.staticfiles', 'django.consortingb.sitemaps', # Uncomment the next line to enable the admin: 'django.consortingb.admin', # Uncomment the next line to enable admin documentation: 'storages', 'django.consortingb.admindocs', 'main', 'contacts', 'piston', 'registration', # 'contact_form', 'basic', 'basic.blog', ) # A sample logging configuration. The only tangible logging # performed by this configuration is to send an email to # the site admins on every HTTP 500 error. # See http://docs.djangoproject.com/en/dev/topics/logging for # more details on how to customize your logging configuration. LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler' } }, 'loggers': { 'django.request': { 'handlers': ['mail_admins'], 'level': 'DEBUG', 'propagate': True, }, 'django.db.backends': { 'handlers': ['mail_admins'], 'level': 'DEBUG', 'propagate': True, } } } DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' AWS_ACCESS_KEY_ID = '' AWS_SECRET_ACCESS_KEY = '' STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage' AWS_STORAGE_BUCKET_NAME = "donebox-static" STATIC_FILES_BUCKET = "donebox-static" MEDIA_FILES_BUCKET = "donebox-media" ACCOUNT_ACTIVATION_DAYS = 7 EMAIL_HOST = "email-smtp.us-east-1.amazonaws.com" EMAIL_HOST_USER = '' EMAIL_HOST_PASSWORD = '' EMAIL_PORT = 587 EMAIL_USE_TLS = True TEMPLATE_CONTEXT_PROCESSORS = ( "django.consortingb.auth.context_processors.auth", "django.core.context_processors.debug", "django.core.context_processors.i18n", "django.core.context_processors.media", "django.core.context_processors.static", "django.consortingb.messages.context_processors.messages", "DoneBox.main.context_processors_PandC", ) 

Contenu de requirements.pip:

 django==1.3 django-storages==1.1.4 django-registration==0.8 django-piston==0.2.3 django-tagging==0.3.1 django-extensions==0.8 BeautifulSoup==3.2.1 boto==2.4.1 mysql-python==1.2.3 tweepy==1.9 feedparser==5.1.2 pycrypto==2.6 

Une recherche google pour cette exception ne donne rien d’intéressant. Je soupçonne que j’ai mal configuré les choses, même si je ne suis pas sûr. Quelqu’un peut-il m’indiquer la bonne direction? Merci pour votre temps et votre considération.

    J’utilise Amazon IAM pour l’identifiant de clé et la clé d’access spécifiques et je viens juste de tomber sur le même 403 Forbidden … Il s’avère que vous devez accorder des permissions qui ciblent à la fois la racine du compartiment et ses sous-objects:

     { "Statement": [ { "Principal": { "AWS": "*" }, "Effect": "Allow", "Action": "s3:*", "Resource": ["arn:aws:s3:::bucket-name/*", "arn:aws:s3:::bucket-name"] } ] } 

    Je vous recommande d’essayer séparément vos informations d’identification AWS pour vérifier si les informations d’identification sont réellement autorisées à lire et à écrire des données dans le compartiment S3. Les éléments suivants devraient fonctionner:

     >>> import boto >>> s3 = boto.connect_s3('', '') >>> bucket = s3.lookup('donebox-static') >>> key = bucket.new_key('testkey') >>> key.set_contents_from_ssortingng('This is a test') >>> key.exists() >>> key.delete() 

    Vous devriez essayer le même test avec l’autre compartiment (‘donebox-media’). Si cela fonctionne, les permissions sont correctes et le problème réside dans le code ou la configuration de stockage Django. Si cela échoue avec un 403 alors soit:

    • Les chaînes access_key / secret_key sont incorrectes
    • Les clés access_key / secret_key sont correctes, mais ce compte ne dispose pas des permissions nécessaires pour écrire dans le compartiment.

    J’espère que ça aide. Veuillez rapporter vos conclusions.

    J’ai eu le même problème et j’ai finalement découvert que le vrai problème était le TEMPS SERVEUR. Il a été mal configuré et AWS répond avec un 403 FORBIDDEN.

    En utilisant Debian, vous pouvez configurer automatiquement avec NTP:

    ntpdate 0.pool.ntp.org

    Cela se produira également si les parameters d’heure de votre machine sont incorrects

    Il est également possible que les identifiants erronés soient utilisés. Vérifier:

     import boto s3 = boto.connect_s3('', '') bucket = s3.get_bucket('') # does this work? s3 = boto.connect_s3() s3.aws_access_key_id # is the same key being used by default? 

    Sinon, regardez ~/.boto , ~/.aws/config et ~/.aws/credentials .

    Au cas où cela aiderait quelqu’un, je devais append l’entrée de configuration suivante pour collectstatic et ne pas renvoyer 403:

     AWS_DEFAULT_ACL = '' 

    Voici un raffinement avec des permissions minimales. Dans tous les cas, comme discuté ailleurs, s3:ListAllMyBuckets est nécessaire sur tous les s3:ListAllMyBuckets .

    Dans sa configuration par défaut, django-storages télécharge les fichiers vers S3 avec des permissions de lecture publique – voir django-storages backend Amazon S3

    Un essai et une erreur ont révélé que dans cette configuration par défaut, les deux seules permissions requirejses étaient s3:PutObject pour télécharger un fichier en premier lieu et s3:PutObjectAcl pour définir les permissions pour cet object sur public.

    Aucune action supplémentaire n’est requirejse car à partir de ce moment, la lecture anticipée est publique sur l’object.

    Politique utilisateur IAM – lecture publique (par défaut):

     { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:ListAllMyBuckets", "Resource": "arn:aws:s3:::*" }, { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:PutObjectAcl" ], "Resource": "arn:aws:s3:::bucketname/*" } ] } 

    Il n’est pas toujours souhaitable d’avoir des objects lisibles publiquement. Pour ce faire, définissez la propriété appropriée dans le fichier de parameters.

    Paramètres Django.py:

     ... AWS_DEFAULT_ACL = "private" ... 

    Et puis le s3:PutObjectAcl n’est plus requirejs et les permissions minimales sont les suivantes:

    Politique utilisateur IAM – privée:

     { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:ListAllMyBuckets", "Resource": "arn:aws:s3:::*" }, { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject" ], "Resource": "arn:aws:s3:::bucketname/*" } ] } 

    Une autre solution évitant les stratégies personnalisées et utilisant des stratégies prédéfinies par AWS:

    • Ajoutez les permissions d’access complet S3 à votre utilisateur S3.

      • IAM / Utilisateurs / Autorisations et stratégie d’attachement
      • Ajouter une politique “AmazonS3FullAccess”

    Vous n’avez peut-être pas access au compartiment que vous essayez de rechercher / obtenir / créer.

    Rappelez-vous que les noms de compartiment doivent être uniques dans l’ensemble de l’ écosystème S3 . Si vous essayez d’accéder à (rechercher / obtenir / créer) un compartiment nommé «test», vous n’y aurez pas access.