Object Storage Swift - Mettre en place CORS sur Object Storage

Voir en Markdown

Retrouvez ici les concepts permettant de mettre en oeuvre CORS.

Objectif

CORS est un mĂ©canisme qui permet au code s'exĂ©cutant dans un navigateur (Javascript, par exemple) de faire des requĂȘtes vers un domaine autre que celui d'oĂč il provient.

Swift supporte les requĂȘtes CORS vers les conteneurs et les objets.

Les mĂ©tadonnĂ©es CORS ne sont prĂ©sentes que dans le conteneur. Les valeurs indiquĂ©es s'appliquent au conteneur lui-mĂȘme et Ă  tous les objets qu'il contient.

Ce guide a pour objectif de vous familiariser avec le concept de CORS.

Prérequis

En pratique

Il existe 3 métadonnées permettant de gérer le CORS sur un conteneur :

MétadonnéesDescription
X-Container-Meta-Access-Control-Allow-OriginOrigins autorisĂ©s Ă  faire des requĂȘtes Cross Origin, sĂ©parĂ©s par un espace.
X-Container-Meta-Access-Control-Max-AgeDurée maximale pendant laquelle l'origins peut conserver les résultats du contrÎle préalable.
X-Container-Meta-Access-Control-Expose-HeadersEn-tĂȘtes exposĂ©s Ă  l'agent utilisateur (par exemple, le navigateur) dans la rĂ©ponse Ă  la demande rĂ©elle. SĂ©parĂ©s par un espace.

Contexte

swift stat <conteneur>
                           Account: AUTH_702xxxxxxxxxxxxxxxxxxxxxxxxxxdaf
                         Container: <conteneur>
                           Objects: 37
                             Bytes: 973749
                          Read ACL: .r:*
                         Write ACL:
                           Sync To:
                          Sync Key:
                  X-Storage-Policy: PCS
                     Accept-Ranges: bytes
                     Last-Modified: Mon, 02 Aug 2021 12:31:18 GMT
                       X-Timestamp: 1627890032.63094
                      Content-Type: text/plain; charset=utf-8
                              Vary: Accept
                        X-Trans-Id: tx3aa56a4d95b44bfb901b8-006107e597
            X-Openstack-Request-Id: tx3aa56a4d95b44bfb901b8-006107e597
                 X-Iplb-Request-Id: 6DBEFE1E:90B8_3626E64B:01BB_6107E597_4276574:220B
                   X-Iplb-Instance: 33617

Définition des métadonnées CORS

CORS spécifie un caractÚre générique *, qui autorise l'accÚs à tous les agents utilisateurs, indépendamment du domaine, du protocole ou de l'hÎte. Bien qu'il existe des cas d'utilisation valables pour cette approche, elle permet également à un acteur malveillant de créer un fac-similé convaincant d'une interface utilisateur et d'inciter les utilisateurs à révéler leurs informations d'authentification. Veuillez évaluer soigneusement votre cas d'utilisation et la documentation pertinente pour éviter tout risque pour votre organisation.

Info

La spécification CORS ne prend pas en charge l'utilisation de ce caractÚre générique dans le cadre d'un URI. La définition de allowed_origin à * fonctionnerait, mais pas *.example.com.

Warning

Si le serveur tourne sur un port non standard, il faut le préciser: http://example.com:8080

swift post -H 'X-Container-Meta-Access-Control-Allow-Origin: http://example.com' `<conteneur>`
swift post -H 'X-Container-Meta-Access-Control-Max-Age:3600' `<conteneur>`
swift post -H 'X-Container-Meta-Access-Control-Expose-Headers:X-Container-Meta-Access-Control-Allow-Origin' `<conteneur>`
# stat
swift stat `<conteneur>`
                             Account: AUTH_702xxxxxxxxxxxxxxxxxxxxxxxxxxdaf
                           Container: `<conteneur>`
                             Objects: 37
                               Bytes: 973749
                            Read ACL: .r:*
                           Write ACL:
                             Sync To:
                            Sync Key:
         Meta Access-Control-Max-Age: 3600
  Meta Access-Control-Expose-Headers: Meta Access-Control-Allow-Origin
    Meta Access-Control-Allow-Origin: http://example.com
                       Accept-Ranges: bytes
                    X-Storage-Policy: PCS
                       Last-Modified: Mon, 02 Aug 2021 09:07:41 GMT
                         X-Timestamp: 1627890032.63094
                        Content-Type: text/plain; charset=utf-8
                                Vary: Accept
                          X-Trans-Id: tx42f4221669584167a6ac8-006107e56e
              X-Openstack-Request-Id: tx42f4221669584167a6ac8-006107e56e
                   X-Iplb-Request-Id: 6DBEFE1E:9094_3626E64B:01BB_6107E56E_4CFC50A:15BC1
                     X-Iplb-Instance: 38427

Page de démonstration

Hébergez la page html suivante sur le serveur web correspondant au CORS origin.

cors.html :

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale="1.0"">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Test CORS</title>
  </head>
  <body>

    Token<br/><input id="token" type="text" size="64"><br/><br/>

    Method<br/>
    <select id="method">
        <option value="GET">GET</option>
        <option value="HEAD">HEAD</option>
        <option value="POST">POST</option>
        <option value="DELETE">DELETE</option>
        <option value="PUT">PUT</option>
    </select><br/><br/>

    URL (Container or Object)<br/><input id="url" size="64" type="text"><br/><br/>

    <input id="submit" type="button" value="Submit" onclick="submit(); return false;">

    <pre id="response_headers"></pre>
    <p>
    <hr/>
    <pre id="response_body"></pre>

    <script type="text/javascript">
      function submit() {
          var token = document.getElementById('token').value;
          var method = document.getElementById('method').value;
          var url = document.getElementById('url').value;

          document.getElementById('response_headers').textContent = null;
          document.getElementById('response_body').textContent = null;

          var request = new XMLHttpRequest();

          request.onreadystatechange = function (oEvent) {
              if (request.readyState == 4) {
                  responseHeaders = 'Status: ' + request.status;
                  responseHeaders = responseHeaders + '\nStatus Text: ' + request.statusText;
                  responseHeaders = responseHeaders + '\n\n' + request.getAllResponseHeaders();
                  document.getElementById('response_headers').textContent = responseHeaders;
                  document.getElementById('response_body').textContent = request.responseText;
              }
          }

          request.open(method, url);
          if (token != '') {
              // custom headers always trigger a pre-flight request
              request.setRequestHeader('X-Auth-Token', token);
          }
          request.send(null);
      }
    </script>

  </body>
</html>

Request Headers

GET /v1/AUTH_702xxxxxxxxxxxxxxxxxxxxxxxxxxdaf/pcs-web/lorem.txt HTTP/1.1
Host: storage.gra.cloud.ovh.net
Connection: keep-alive
sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"
X-Auth-Token: gAAAAABhB60RtB6kbTjksGne23pvSiW1X24BjFzpgInOeoXomd21etqpLw6ocys4SuC9PHZ3PfVMCHIMvb6yjyoEwg1XY2iWfcenCMOhG7POgv-i2NePNJSkjc9cE0eVTDEQ-VhtcOCc-ZvbU459a0HpsWUbGMwn8bUi4-hl3Cv5bwGgLuBxmbw
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
Accept: */*
Origin: http://example.com
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://example.com
Accept-Encoding: gzip, deflate, br
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
If-None-Match: 51f122f524c46cafcf9628305db99144
If-Modified-Since: Tue, 03 Aug 2021 07:10:26 GMT

Response Headers

HTTP/1.1 200 OK
Access-Control-Expose-Headers: expires, content-language, cache-control, meta, X-Container-Read, X-Storage-Policy, last-modified, etag, x-timestamp, pragma, x-trans-id, access-control-allow-origin, content-type, x-openstack-request-id, x-object-meta-mtime
Accept-Ranges: bytes
Last-Modified: Tue, 03 Aug 2021 07:10:26 GMT
X-Timestamp: 1627974625.84403
Access-Control-Allow-Origin: http://example.com
X-Object-Meta-Mtime: 1627974571.298786
X-Trans-Id: txdf16d14f7cbd4d0b83b5c-006108f198
X-Openstack-Request-Id: txdf16d14f7cbd4d0b83b5c-006108f198
Date: Tue, 03 Aug 2021 07:34:49 GMT
X-IPLB-Request-ID: 58AB65BB:76FF_3626E64B:01BB_6108F198_41D39CC:10AC4
X-IPLB-Instance: 12309
Content-Length: 746
Content-Type: text/plain
Etag: 51f122f524c46cafcf9628305db99144

Avant qu'un navigateur n'émette une demande réelle, il peut émettre une demande de contrÎle préalable. La demande de contrÎle préalable est un appel destiné à vérifier que l'origine est autorisée à effectuer la demande. La séquence des événements est la suivante :

  • Le navigateur envoie une demande OPTIONS Ă  Swift.
  • Swift renvoie 200/401 au navigateur en fonction des origins autorisĂ©es.
  • Si 200, le navigateur effectue la « demande rĂ©elle » Ă  Swift, c'est-Ă -dire PUT, POST, DELETE, HEAD, GET.

Lorsqu'un navigateur reçoit une rĂ©ponse Ă  une demande rĂ©elle, il n'expose que les en-tĂȘtes Ă©numĂ©rĂ©s dans l'en-tĂȘte Access-Control-Expose-Headers. Par dĂ©faut, Swift renvoie les valeurs suivantes pour cet en-tĂȘte :

  • « simple-response-header » telles qu'elles sont listĂ©es sur http://www.w3.org/TR/cors/#simple-response-header
  • Les en-tĂȘtes etag, x-timestamp, x-trans-id, x-openstack-request-id.
  • Tous les en-tĂȘtes de mĂ©tadonnĂ©es (X-Container-Meta-* pour les conteneurs et X-Object-Meta-* pour les objets).
  • Les en-tĂȘtes Ă©numĂ©rĂ©s dans X-Container-Meta-Access-Control-Expose-Headers.
  • Les en-tĂȘtes configurĂ©s Ă  l'aide de l'option cors_expose_headers dans proxy-server.conf.

Supprimer les métadonnées CORS

swift post -H "X-Remove-Container-Meta-Access-Control-Allow-Origin:x" `<conteneur>`
swift post -H "X-Remove-Container-Meta-Access-Control-Max-Age:x" `<conteneur>`
swift post -H "X-Remove-Container-Meta-Access-Control-Expose-Headers:x" `<conteneur>`
# stat
swift stat `<conteneur>`
                           Account: AUTH_702xxxxxxxxxxxxxxxxxxxxxxxxxxdaf
                         Container: `<conteneur>`
                           Objects: 37
                             Bytes: 973749
                          Read ACL: .r:*
                         Write ACL:
                           Sync To:
                          Sync Key:
                  X-Storage-Policy: PCS
                     Accept-Ranges: bytes
                     Last-Modified: Mon, 02 Aug 2021 12:31:18 GMT
                       X-Timestamp: 1627890032.63094
                      Content-Type: text/plain; charset=utf-8
                              Vary: Accept
                        X-Trans-Id: tx3aa56a4d95b44bfb901b8-006107e597
            X-Openstack-Request-Id: tx3aa56a4d95b44bfb901b8-006107e597
                 X-Iplb-Request-Id: 6DBEFE1E:90B8_3626E64B:01BB_6107E597_4276574:220B
                   X-Iplb-Instance: 33617

Aller plus loin

Si vous avez besoin d'une formation ou d'une assistance technique pour la mise en oeuvre de nos solutions, contactez votre commercial ou cliquez sur ce lien pour obtenir un devis et demander une analyse personnalisĂ©e de votre projet Ă  nos experts de l’équipe Professional Services.

Échangez avec notre communautĂ© d’utilisateurs.

Cette page vous a-t-elle aidé ?