Prise en charge du service CORS (Cross-Origin Resource Sharing) pour le Stockage Azure

Depuis la version du 15/08/2013, les services de stockage Azure prennent en charge le Partage de ressources cross-origine (CORS) pour les services BLOB, de Table et de File d'attente. Le service Fichiers prend en charge CORS à compter de la version 2015-02-21.

CORS est une fonctionnalité HTTP qui permet à une application web exécutée dans un domaine d'accéder aux ressources d'un autre domaine. Les navigateurs web implémentent une restriction de sécurité appelée stratégie de même origine qui empêche une page web d’appeler des API d’un autre domaine ; CORS constitue un moyen sûr pour autoriser un domaine (le domaine d’origine) à appeler des API d’un autre domaine. Pour plus d’informations sur CORS, consultez la spécification CORS .

Vous pouvez définir des règles CORS individuellement pour chacun des services stockage Azure en appelant Définir les propriétés du service Blob, Définir les propriétés du service de fichiers, Définir les propriétés du service de file d’attente et Définir les propriétés du service de table. Une fois que vous avez défini les règles CORS du service, une requête autorisée exécutée auprès du service à partir d'un autre domaine est évaluée pour déterminer si elle est autorisée conformément aux règles que vous avez spécifiées.

Important

CORS n’est pas un mécanisme d’autorisation. Toute requête effectuée sur une ressource de stockage lorsque CORS est activé doit avoir un en-tête d’autorisation valide ou doit être effectuée sur une ressource publique.

CORS est pris en charge pour tous les types de comptes de stockage, à l’exception des comptes de stockage v1 ou v2 à usage général dans le niveau de performances Premium.

Présentation des demandes CORS

Une demande CORS d'un domaine d'origine peut comprendre deux demandes distinctes :

  • Une demande préliminaire, qui interroge les restrictions CORS imposées par le service. La demande préliminaire est obligatoire, sauf si la méthode de demande est une méthode simple, à savoir GET, HEAD ou POST.

  • La demande réelle, adressée à la ressource souhaitée.

Demande préliminaire

La demande préliminaire interroge les restrictions CORS qui ont été établies pour le service de stockage par le propriétaire du compte. Le navigateur web (ou tout autre agent utilisateur) envoie une demande OPTIONS qui comprend les en-têtes de demande, la méthode et le domaine d'origine. Le service de stockage évalue l'opération prévue selon un ensemble préconfiguré de règles CORS qui indiquent les domaines d'origine, les méthodes de demande et les en-têtes de demande qui peuvent être spécifiés dans une demande réelle à une ressource de stockage.

Si CORS est activé pour le service et que l'une des règles CORS correspond à la demande préliminaire, le service répond avec le code d'état 200 (OK) et inclut les en-têtes Access-Control dans la réponse.

Si CORS n'est pas activé pour le service ou si aucune règle CORS ne correspond à la demande préliminaire, le service répond avec le code d'état 403 (Interdit).

Si la demande OPTIONS ne contient pas les en-têtes CORS nécessaires (en-têtes Origin et Access-Control-Request-Method), le service répond avec le code d'état 400 (Demande incorrecte).

Notez qu’une demande de contrôle préliminaire est évaluée par rapport au service (Blob, File, File, Queue ou Table) et non par rapport à la ressource demandée. Le propriétaire du compte doit avoir activé CORS en définissant les propriétés de service de compte appropriées pour que la demande réussisse.

Demande réelle

Une fois la demande préliminaire acceptée et la réponse retournée, le navigateur envoie la demande réelle sur la ressource de stockage. Le navigateur refuse immédiatement la demande réelle si la demande préliminaire est rejetée.

La demande réelle est traitée comme une demande normale au service de stockage. La présence de l'en-tête Origin indique que la demande est une demande CORS et que le service vérifiera les règles CORS correspondantes. Si une correspondance est trouvée, les en-têtes Access-Control sont ajoutés à la réponse et renvoyés au client. Si aucune correspondance n'est trouvée, les en-têtes Access-Control CORS ne sont pas renvoyés.

Activation de CORS pour Stockage Azure

Les règles CORS étant définies au niveau du service, vous devez activer ou désactiver CORS pour chaque service (blob, fichier, file d’attente et table) séparément. Par défaut, CORS est désactivé pour chacun des services. Pour activer CORS, vous devez définir les propriétés de service appropriées à l’aide de la version 2013-08-15 ou ultérieure pour les services Blob, File d’attente et Table, ou version 2015-02-21 ou pour le service De fichiers. Vous activez CORS en ajoutant des règles CORS aux propriétés du service. Pour plus d’informations sur l’activation ou la désactivation de CORS pour un service et sur la définition de règles CORS, consultez Définir les propriétés du service Blob, Définir les propriétés du service de fichiers, Définir les propriétés du service de table et Définir les propriétés du service de file d’attente.

Voici un exemple d’une règle CORS unique, spécifiée via une Set Service Properties opération :

<Cors>
    <CorsRule>  
        <AllowedOrigins>http://*.contoso.com, http://www.fabrikam.com</AllowedOrigins>  
        <AllowedMethods>PUT,GET</AllowedMethods>  
        <AllowedHeaders>x-ms-meta-data*,x-ms-meta-target*,x-ms-meta-abc</AllowedHeaders>  
        <ExposedHeaders>x-ms-meta-*</ExposedHeaders>  
        <MaxAgeInSeconds>200</MaxAgeInSeconds>  
    </CorsRule>  
<Cors>  
  

Chaque élément inclus dans la règle CORS est décrit ci-dessous :

  • AllowedOrigins : Domaines d’origine qui sont autorisés à effectuer une requête auprès du service de stockage via CORS. Le domaine d'origine est celui d'où provient la demande. Notez que l'origine doit correspondance exactement (avec respect de la casse) à l'origine que l'utilisateur envoie au service.

    Vous pouvez utiliser le caractère générique « * » au lieu d’un domaine spécifié pour permettre à tous les domaines d’origine d’effectuer des requêtes via CORS. Vous pouvez également utiliser le caractère générique au lieu d’un sous-domaine pour permettre à tous les sous-domaines d’un domaine donné d’effectuer des requêtes via CORS. Dans l’exemple ci-dessus, tous les sous-domaines de peuvent effectuer des contoso.com requêtes via CORS, tandis que seules les requêtes du www sous-domaine de fabrikam.com sont autorisées via CORS.

  • AllowedMethods : Méthodes (verbes de requête HTTP) que le domaine d’origine peut utiliser pour une requête CORS. Dans l'exemple ci-dessus, seules les demandes PUT et GET sont autorisées.

  • AllowedHeaders : En-têtes de requête que le domaine d’origine peut spécifier dans la requête CORS. Dans l'exemple ci-dessus, tous les en-têtes de métadonnées commençant par x-ms-meta-data, x-ms-meta-target et x-ms-meta-abc sont autorisés. Notez que le caractère générique « * » indique que les en-têtes commençant par le préfixe spécifié sont autorisés.

  • ExposedHeaders : En-têtes de réponse qui peuvent être envoyés dans la réponse à la requête CORS et exposés par le navigateur à l’émetteur de la requête. Dans l'exemple ci-dessus, il est indiqué au navigateur d'exposer les en-têtes commençant par x-ms-meta.

  • MaxAgeInSeconds : Durée maximale pendant laquelle un navigateur doit mettre en cache la requête OPTIONS préliminaire.

Les services de stockage Azure prennent en charge la spécification d’en-têtes préfixés pour les éléments AllowedHeaders et ExposedHeaders. Pour autoriser une catégorie d'en-têtes, vous pouvez spécifier un préfixe commun à cette catégorie. Par exemple, le fait de spécifier x-ms-meta* comme en-tête préfixé établit une règle qui correspond à tous les en-têtes commençant par x-ms-meta.

Les limitations suivantes s'appliquent aux règles CORS :

  • Vous pouvez spécifier jusqu’à cinq règles CORS par service de stockage (Blob, File, Table et File d’attente).

  • La taille maximale de tous les paramètres de règles CORS sur la demande, à l’exception des balises XML, ne doit pas dépasser 2 Kio.

  • La longueur d'un en-tête autorisé, d'un en-tête exposé ou d'une origine autorisée ne doit pas dépasser 256 caractères.

  • Les en-têtes autorisés et les en-têtes exposés peuvent être :

    • des en-têtes littéraux, où le nom exact de l’en-tête est spécifié, tel que x-ms-meta-processed. Il ne peut pas y avoir plus de 64 en-têtes littéraux spécifiés sur la demande ;
    • Des en-têtes préfixés, où un préfixe de l'en-tête est spécifié, tel que x-ms-meta-data*. Le fait de spécifier un préfixe de cette façon autorise ou expose tout en-tête qui commence par le préfixe donné. Il ne peut pas y avoir plus de deux en-têtes préfixés spécifiés sur la demande.
  • Les méthodes (ou verbes HTTP) spécifiées dans l’élément AllowedMethods doivent respecter les méthodes prises en charge par les API de service de stockage Azure. Les méthodes prises en charge sont DELETE, GET, HEAD, MERGE, POST, PATCH, OPTIONS et PUT.

Présentation de la logique d'évaluation des règles CORS

Quand un service de stockage reçoit une demande préliminaire ou réelle, il évalue cette demande en fonction des règles CORS que vous avez créées pour le service via l'opération Set Service Properties appropriée. Les règles CORS sont évaluées dans l'ordre dans lequel elles ont été définies dans le corps de la demande de l'opération Set Service Properties.

Les règles CORS sont évaluées comme suit :

  1. Tout d'abord, le domaine d'origine de la demande est vérifié par rapport aux domaines répertoriés pour l'élément AllowedOrigins. Si le domaine d'origine figure dans la liste ou si tous les domaines sont autorisés avec le caractère générique « * », l'évaluation des règles continue. Si le domaine d'origine ne figure pas dans la liste, la demande échoue.

  2. Ensuite, la méthode (ou le verbe HTTP) de la demande est comparée aux méthodes répertoriées dans l'élément AllowedMethods. Si la méthode figure dans la liste, l'évaluation des règles continue ; sinon, la demande échoue.

  3. Si la demande correspond à une règle dans son domaine d'origine et sa méthode, cette règle est sélectionnée pour traiter la demande et aucune autre règle n'est évaluée. Pour que la demande réussisse, tous les en-têtes spécifiés dans la demande sont vérifiés par rapport aux en-têtes répertoriés dans l'élément AllowedHeaders. Si les en-têtes envoyés ne correspondent pas aux en-têtes autorisés, la demande échoue.

Étant donné que les règles sont traitées dans l'ordre dans lequel elles sont indiquées dans le corps de la demande, il est recommandé de spécifier les règles les plus restrictives en ce qui concerne les origines en premier dans la liste, afin qu'elles soient évaluées en priorité. Spécifiez les règles les moins restrictives (par exemple, une règle pour autoriser toutes les origines) à la fin de la liste.

Exemple : évaluation de règles CORS

L'exemple suivant illustre un corps de demande partiel pour une opération visant à définir des règles CORS pour les services de stockage. Pour plus d’informations sur la construction de la demande, consultez Définir les propriétés du service blob, Définir les propriétés du service de file d’attente et Définir les propriétés du service de table .

<Cors>  
    <CorsRule>  
        <AllowedOrigins>http://www.contoso.com</AllowedOrigins>  
        <AllowedMethods>PUT,HEAD</AllowedMethods>  
        <MaxAgeInSeconds>5</MaxAgeInSeconds>  
        <ExposedHeaders>x-ms-*</ExposedHeaders>  
        <AllowedHeaders>x-ms-blob-content-type, x-ms-blob-content-disposition</AllowedHeaders>  
    </CorsRule>  
    <CorsRule>  
        <AllowedOrigins>*</AllowedOrigins>  
        <AllowedMethods>PUT,GET</AllowedMethods>  
        <MaxAgeInSeconds>5</MaxAgeInSeconds>  
        <ExposedHeaders>x-ms-*</ExposedHeaders>  
        <AllowedHeaders>x-ms-blob-content-type, x-ms-blob-content-disposition</AllowedHeaders>  
    </CorsRule>  
    <CorsRule>  
        <AllowedOrigins>http://www.contoso.com</AllowedOrigins>  
        <AllowedMethods>GET</AllowedMethods>  
        <MaxAgeInSeconds>5</MaxAgeInSeconds>  
        <ExposedHeaders>x-ms-*</ExposedHeaders>  
        <AllowedHeaders>x-ms-client-request-id</AllowedHeaders>  
    </CorsRule>  
</Cors>

Ensuite, tenez compte des demandes CORS suivantes :

Méthode Origine En-têtes de requête Correspondance de règle Résultat
PUT http://www.contoso.com x-ms-blob-content-type Première règle Succès
GET http://www.contoso.com x-ms-blob-content-type Deuxième règle Succès
GET http://www.contoso.com x-ms-client-request-id Deuxième règle Échec

La première demande correspond à la première règle (le domaine d'origine correspond aux origines autorisées, la méthode correspond aux méthodes autorisées et l'en-tête correspond aux en-têtes autorisés). Par conséquent, elle réussit.

La deuxième demande ne correspond pas à la première règle, car la méthode ne correspond pas aux méthodes autorisées. Toutefois, elle correspond à la deuxième règle, donc elle réussit.

La troisième demande correspond à la deuxième règle en ce qui concerne le domaine d'origine et la méthode, donc aucune autre règle n'est évaluée. Toutefois, l'en-tête x-ms-client-request-id n'est pas autorisé par la deuxième règle, donc la demande échoue, en dépit du fait que la sémantique de la troisième règle lui aurait permis de réussir.

Notes

Bien que cet exemple illustre une règle moins restrictive avant une règle plus restrictive, il est généralement recommandé de répertorier les règles les plus restrictives en premier.

Présentation de la définition de l'en-tête Vary

L'en-tête Vary est un en-tête HTTP/1.1 standard composé d'un ensemble de champs d'en-tête de demande qui indiquent au navigateur ou à l'agent utilisateur les critères qui ont été sélectionnés par le serveur pour traiter la demande. L'en-tête Vary est principalement utilisé pour la mise en cache par les proxys, les navigateurs et les réseaux de distribution de contenu, qui s'en servent pour déterminer comment la réponse doit être mise en cache. Pour plus d’informations, consultez la spécification de l’ en-tête Vary.

Lorsque le navigateur ou un autre agent utilisateur met en cache la réponse d'une demande CORS, le domaine d'origine est mis en cache comme origine autorisée. Quand un deuxième domaine émet la même demande pour une ressource de stockage pendant que le cache est actif, l'agent utilisateur récupère le domaine d'origine mis en cache. Comme le deuxième domaine ne correspond pas au domaine mis en cache, la demande échoue (alors qu'elle devrait réussir en d'autres circonstances). Dans certains cas, Stockage Azure définit l’en-tête Vary sur Origin pour indiquer à l’agent utilisateur d’envoyer la requête CORS suivante au service lorsque le domaine demandeur diffère de l’origine mise en cache.

Stockage Azure définit l’en-tête VaryOrigin sur pour les demandes GET/HEAD réelles dans les cas suivants :

  • Lorsque l'origine de la demande correspond exactement à l'origine autorisée définie par une règle CORS. Pour être une correspondance exacte, la règle CORS ne doit pas inclure de caractère générique « * ».

  • Il n'y a aucune règle correspondant à l'origine de la demande, mais CORS est activé pour le service de stockage.

Si une demande GET/HEAD correspond à une règle CORS qui autorise toutes les origines, la réponse indique que toutes les origines sont autorisées et le cache de l'agent utilisateur autorise les demandes suivantes à partir de n'importe quel domaine d'origine pendant que le cache est actif.

Notez qu'en ce qui concerne les demandes à l'aide de méthodes autres que GET/HEAD, les services de stockage ne définissent pas l'en-tête Vary, car les réponses à ces méthodes ne sont pas mises en cache par les agents utilisateurs.

Le tableau suivant indique comment le stockage Azure répond aux demandes GET/HEAD en fonction des cas mentionnés précédemment :

En-tête d’origine présent dans la demande Règle(s) CORS spécifiée(s) pour ce service Il existe une règle de correspondance qui autorise toutes les origines (*) Règle de correspondance existante pour la correspondance exacte d’origine La réponse inclut l’en-tête Vary avec la valeur Origin La réponse inclut l’en-tête Access-Control-Allowed-Origin : « * » La réponse inclut l’en-têteAccess-Control-Exposed-Headers
Non Non Non Non Non Non Non
Non Oui Non Non Oui Non Non
Non Oui Oui Non Non Oui Oui
Oui Non Non Non Non Non Non
Oui Oui Non Oui Oui Non Oui
Oui Oui Non Non Oui Non Non
Oui Oui Oui Non Non Oui Oui

Facturation des demandes CORS

Les demandes de contrôle préalable réussies sont facturées si vous avez activé CORS pour l’un des services de stockage de votre compte (en appelant Définir les propriétés du service Blob, Définir les propriétés du service de file d’attente, Définir les propriétés du service de fichiers ou Définir les propriétés du service table). Pour réduire les frais, envisagez d'affecter une valeur plus élevée à l'élément MaxAgeInSeconds dans vos règles CORS, de façon à ce que l'agent utilisateur mette en cache la demande.

Les demandes préliminaires infructueuses ne seront pas facturés.

Voir aussi

Spécification du Partage des ressources cross-origin (W3C)