How to enable CORS while accessing Object Storage Containers on CloudFerro Cloud

../_images/button_orange_cf23.png

If you want to access your objects in your Object Store Container from another domain, you will encounter the CORS problem. CORS stands for Cross-Origin Resource Sharing and is a standard that serves to relax the same-origing policy for a web site. Examples of CORS related problems are:

  • Header ‘Origin’ cannot be added

  • Header ‘Access-Control-Allow-Origin’ missing

  • CORS preflight channel did not succeed

and there are many others.

The article will show how to configure your container to enable CORS.

Let’s assume, that you have already created two files in a container:

../_images/nwt_image1.png

If you make the container public by checking the Public Access checkbox, you can get the link to the objects by clicking on Link.

Then you can access the objects by inserting the link (e.g. https://s3.waw2-1.cloudferro.com/swift/v1/AUTH_8b72c381c7724c44b971e6a5862a0b94/container-nr-1/) into your browser:

../_images/nwt_pasted_image002.png

We will simulate the CORS problem by using the file from the OpenStack article:

https://docs.openstack.org/swift/latest/cors.html#test-cors-page

The file is the following:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <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>

Please open the file in the browser:

../_images/nwt_test_cors.png

Insert the link obtained previously: https://s3.waw2-1.cloudferro.com/swift/v1/AUTH_8b72c381c7724c44b971e6a5862a0b94/container-nr-1/

Now click on “Submit” button:

../_images/nwt_pasted_image003.png

If you open console in the browser, you will see the message informing that access was blocked.

Now prepare the Python environment according to one these articles:

How to install OpenStackClient GitBash for Windows on CloudFerro Cloud

How to install OpenStackClient on Windows using Windows Subsystem for Linux on CloudFerro Cloud OpenStack Hosting

How to install OpenStackClient for Linux on CloudFerro Cloud

and source the RC file:

$ source jdoe-test.sh
Please enter your OpenStack Password for project test_project as user [email protected]:

You can check if you can see the container and objects by invoking the following commands:

$ openstack container list
+----------------+
| Name           |
+----------------+
| container-nr-1 |
+----------------+

$ openstack object list container-nr-1
+---------------+
| Name          |
+---------------+
| file-nr-1.txt |
| file-nr-2.txt |
+---------------+

Now you should generate EC2 credentials according to the article:

How to generate and manage EC2 credentials on CloudFerro Cloud

$ openstack ec2 credentials create -f json
{
  "access": "<access code>",
  "access_token_id": null,
  "links": {
    "self": "https://cf2.cloudferro.com:5000/v3/users/<user id>/credentials/OS-EC2/<access code>"
  },
  "project_id": "8b72c381c7724c44b971e6a5862a0b94",
  "secret": "<secret code>",
  "trust_id": null,
  "user_id": "<user id>"
}

Now you need to configure s3cmd tool

/s3/How-to-access-private-object-storage-using-S3cmd-or-boto3-on-Creodias

Below is the simplified configuration:

You need to create a config file e.g. jdoe-test-s3cfg, with the following content:

location = US
access_key = <access code>
host_base = s3.waw2-1.cloudferro.com
host_bucket = s3.waw2-1.cloudferro.com
secret_key = <secret code>

Now you can check the properties of your container:

$ s3cmd -c jdoe-test-s3cfg info s3://container-nr-1
s3://container-nr-1/ (bucket):
   Location:  dias_default
   Payer:     BucketOwner
   Expiration Rule: none
   Policy:    none
   CORS:      none
   ACL:       test_project: FULL_CONTROL

Now prepare another file: cors.xml

<CORSConfiguration>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

and activate the following command:

$ s3cmd -c jdoe-test-s3cfg setcors cors.xml s3://container-nr-1

Now check the properties of the container:

$ s3cmd -c jdoe-test-s3cfg info s3://container-nr-1
s3://container-nr-1/ (bucket):
   Location:  dias_default
   Payer:     BucketOwner
   Expiration Rule: none
   Policy:    none
   CORS:      <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><CORSRule><AllowedMethod>GET</AllowedMethod><AllowedOrigin>*</AllowedOrigin><AllowedHeader>*</AllowedHeader></CORSRule></CORSConfiguration>
   ACL:       test_project: FULL_CONTROL

and test the cors-test.html file again

../_images/nwt_pasted_image004.png

The screen above shows that CORS has been enabled.