How to enable CORS while accessing Object Storage Containers on CloudFerro Cloud
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:
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 one these articles:
How to install OpenStackClient GitBash for Windows on CloudFerro Cloud
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
The screen above shows that CORS has been enabled.