web-dev-qa-db-fra.com

Configuration correcte de S3 + Cloudfront CORS?

Mon application stocke des images sur S3, puis les transmet par proxy via Cloudfront. Je suis ravi d'utiliser le nouveau support S3 CORS afin de pouvoir utiliser les méthodes de canevas HTML5 (qui ont une politique cross-Origin) mais je n'arrive pas à configurer correctement mon S3 et Cloudfront. Toujours en cours d'exécution "Erreur non capturée: SECURITY_ERR: exception DOM 18" lorsque j'essaie de convertir une image en élément de canevas.

Voici ce que j'ai jusqu'à présent:

S3

<CORSConfiguration>
  <CORSRule>
    <AllowedOrigin>MY_WEBSITE_URL</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
  </CORSRule>
  <CORSRule>
    <AllowedOrigin>MY_CLOUDFRONT_URL</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
    </CORSRule>
  </CORSConfiguration>

Cloudfront

Les origines

Origin Protocol Policy: Match Viewer

HTTP Port: 80

HTTPS Port: 443

Comportements

Origin: MY_WEBSITE_URL

Object Caching: Use Origin Cache Headers

Forward Cookies: None

Forward Query Strings: Yes

Y a-t-il quelque chose qui me manque ici?

MISE À JOUR: J'ai juste essayé de changer les en-têtes en

<AllowedHeader>Content-*</AllowedHeader>
<AllowedHeader>Host</AllowedHeader>

basé sur cette question Amazon S3 CORS (Cross-Origin Resource Sharing) et Firefox cross-domain font loading

Toujours pas.

MISE À JOUR: PLUS D'INFO SUR DEMANDE

Request
URL:https://d1r5nr1emc2xy5.cloudfront.net/uploaded/BAhbBlsHOgZmSSImMjAxMi8wOS8xMC8xOC81NC80Mi85NC9ncmFzczMuanBnBjoGRVQ/32c0cee8
Request Method:GET
Status Code:200 OK (from cache)

MISE À JOUR

Je pense que ma demande n'était peut-être pas correcte, j'ai donc essayé d'activer CORS avec

img.crossOrigin = '';

mais alors l'image ne se charge pas et j'obtiens l'erreur: charge d'image Cross-Origin refusée par la stratégie de partage de ressources Cross-Origin.

53
kateray

Le 26 juin 2014, AWS a publié bon comportement Vary: Origin sur CloudFront alors maintenant vous venez

  1. Définissez une configuration CORS pour votre compartiment S3, y compris

    <AllowedOrigin>*</AllowedOrigin>

  2. Dans CloudFront -> Distribution -> Comportements pour cette origine

    • Méthodes HTTP autorisées: + OPTIONS
    • Méthodes HTTP en cache + OPTIONS
    • Cache basé sur les en-têtes de demande sélectionnés: mettez en liste blanche l'en-tête Origin.
  3. Attendez environ 20 minutes pendant que CloudFront propage la nouvelle règle

Désormais, votre distribution CloudFront doit mettre en cache différentes réponses (avec les en-têtes CORS appropriés) pour différents en-têtes d'origine du client.

109
Brett

Pour compléter @ réponse de Brett . Il existe des pages de documentation AWS détaillant CORS sur CloudFront et CORS sur S .

Les étapes détaillées ici sont les suivantes:

  1. Dans votre compartiment S3, accédez à Autorisations -> Configuration CORS
  2. Ajoutez des règles pour CORS dans l'éditeur, le <AllowedOrigin> la règle est la plus importante. Enregistrez la configuration. enter image description here
  3. Dans votre distribution CloudFront, accédez à Comportement -> choisissez un comportement -> Modifier
  4. Selon que vous souhaitez que OPTIONS réponses soient mises en cache ou non, il existe deux manières selon AWS:
  • Si vous souhaitez que les réponses OPTIONS soient mises en cache, procédez comme suit:
    • Choisissez les options des paramètres de comportement de cache par défaut qui permettent la mise en cache des réponses OPTIONS.
    • Configurez CloudFront pour transférer les en-têtes suivants: origine, en-têtes de demande de contrôle d'accès et méthode de demande de contrôle d'accès.
  • Si vous ne souhaitez pas que les réponses OPTIONS soient mises en cache, configurez CloudFront pour transférer l'en-tête Origin, ainsi que tous les autres en-têtes requis par votre origine

enter image description here

Et avec ce CORS de CloudFront avec S3 devrait fonctionner.

24
Christian Eriksson

MISE À JOUR: ce n'est plus vrai avec les changements récents sur CloudFront. Hourra! Voir les autres réponses pour les détails. Je laisse cela ici pour le contexte/l'histoire.

Problème

CloudFront ne prend pas en charge CORS à 100%. Le problème est de savoir comment CloudFront met en cache la réponse à la demande. Toute autre demande pour la même URL après cela entraînera la demande en cache peu importe l'origine. La partie clé à ce sujet est qu'elle inclut les en-têtes de réponse de l'origine.

Première demande avant que CloudFront n'ait quoi que ce soit mis en cache de Origin: http://example.com a un en-tête de réponse:

Access-Control-Allow-Origin: http://example.com

Deuxième demande de Origin: https://example.com (notez qu'il s'agit de HTTPS et non de HTTP) a également l'en-tête de réponse:

Access-Control-Allow-Origin: http://example.com

Parce que c'est ce que CloudFront a mis en cache pour l'URL. Ceci n'est pas valide - la console du navigateur (en Chrome au moins) affichera un message de violation CORS et les choses vont se casser.

Solution

Le travail suggéré consiste à utiliser différentes URL pour différentes origines. L'astuce consiste à ajouter une chaîne de requête unique qui est différente afin qu'il y ait un enregistrement mis en cache par origine.

Donc, nos URL seraient quelque chose comme:

http://.../some.png?http_mysite.com
https://.../some.png?https_mysite.com

Ce genre de travaux, mais n'importe qui peut mal faire fonctionner votre site en échangeant les chaînes de requête. Est-ce probable? Probablement pas, mais le débogage de ce problème est un énorme problème.

La bonne solution consiste à ne pas utiliser CloudFront avec CORS tant qu'ils ne prennent pas pleinement en charge CORS.

En pratique

Si vous utilisez CloudFront pour CORS, utilisez une autre méthode qui fonctionnera lorsque CORS ne fonctionne pas. Ce n'est pas toujours une option mais en ce moment je charge dynamiquement des polices avec JavaScript. Si la demande basée sur CORS à CloudFront échoue, je reviens à un proxy côté serveur pour les polices (pas d'origine croisée). De cette façon, les choses continuent de fonctionner même si CloudFront a en quelque sorte obtenu un mauvais enregistrement mis en cache pour la police.

5
Cymen

Je ne sais pas exactement quel est votre problème, mais:

https://forums.aws.Amazon.com/thread.jspa?messageID=37751

répondu à certains de mes problèmes avec CORS, S3 et Cloudfront.

J'ai également constaté que certains actifs d'un compartiment reviendraient avec les en-têtes CORS corrects et d'autres non. Après avoir invalidé les actifs, ils sont tous revenus avec des en-têtes corrects, ne sachant pas pourquoi certains devaient être invalidés et d'autres pas car ils ont été téléchargés en même temps, même type, même seau :(

2
Jim