How to enable CORS while accessing Object Storage Containers
If you want to access your objects in your Object Store Container from another domain, you will encounter CORS problem.
The article will show how to configure your container to enable CORS.
Let's assume, that you have already created 2 files in a container:
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:
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:
insert the link obtained previously: https://s3.waw2-1.cloudferro.com/swift/v1/AUTH_8b72c381c7724c44b971e6a5862a0b94/container-nr-1/
now click on "Submit" button:
If you open console in the browser, you will see the message informing that access was blocked.
Now prepare the Python environment according to the article:
HOW TO INSTALL OPENSTACKCLIENT (LINUX)?
and source the RC file:
$ source jdoe-test.sh Please enter your OpenStack Password for project test_project as user john.doe@cloudferro.com:
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 ec2 credentials?
$ 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
HOW TO ACCESS PRIVATE OBJECT STORAGE USING S3CMD OR BOTO3?
Below is the simplified configuration:
You need to create a config file e.g. jdoe-test-s3cfg
with the following content:
location = RegionOne 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 invoke 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
The screen above shows that CORS has been enabled.