Swift tempurl middleware

Swift has a middleware called tempurl that allow public access to objects. This feature can be useful when an account owner want to allow access for a foreign user to some objects of his account. A common usage when swift is used as storage backend in a web application is to built the temporary urls server side and let the browser communicate directly with swift for a limited delay. User can target temporary urls using only GET/PUT/HEAD http verbs.
Here we’ll see how to use temporary urls. Our demo Swift installation is a devstack.

First we push two objects in a container with python-swiftclient.

$ swift -A http://192.168.56.101:8080/auth/v1.0 -U admin:admin -K admin upload container openrc
openrc
$ swift -A http://192.168.56.101:8080/auth/v1.0 -U admin:admin -K admin upload container stackrc
stackrc

The tempurl middleware will look at Temp-URL-Key and Temp-URL-Key-2 meta when an object is
requested via a temporary url to allow or not access. Those keys are used to build the temporary signature. Having the ability to set two keys on an account is safer when the owner want to change the key as previous key is still set and let the middleware validate existing temporary urls.

$ swift -A http://192.168.56.101:8080/auth/v1.0 -U admin:admin -K admin post -m Temp-URL-Key:thekey
$ swift -A http://192.168.56.101:8080/auth/v1.0 -U admin:admin -K admin post -m Temp-URL-Key-2:thekey2

Now we want to allow access to the object called openrc in container ‘container’ then we need
to create the temporary URL. Swift comes with a tool called swift-temp-url that is a builder. Give it some arguments, the allowed HTTP method, the availability delay, the object path, and one of the keys set in the account and it will gracefully create the temporary URL for you.

$ ./swift-temp-url GET 6000 /v1/AUTH_admin/container/openrc thekey
/v1/AUTH_admin/container/openrc?temp_url_sig=97d6512e86dbccdfba315172a3c7dcf7463253b9&temp_url_expires=1374241736

The temp_url_sig is really important as it is a hash(hmac-sha1) of the elements the account owner
has allowed, the http method, the object path and the expiration delay. Thus user corruption of the url by changing the object path for instance result of a 401 http error.

The object can be retrieved with any http client.

$ curl http://192.168.56.101:8080/v1/AUTH_admin/container/openrc?temp_url_sig=97d6512e86dbccdfba315172a3c7dcf7463253b9\&temp_url_expires=1374241736

To allow access to our second object ‘stackrc’, we just need to compute a new temporary
url with swift-temp-url.

$ ./swift-temp-url GET 6000 /v1/AUTH_admin/container/stackrc thekey2
/v1/AUTH_admin/container/stackrc?temp_url_sig=f3a665279ff0147a5c885e15cee08939f9eda235&temp_url_expires=1374242123

stackrc and all other objects contained in this account can be targeted according to the path given to swift-temp-url command.

As said above PUT method can be allowed and temporary url can be used to let the user push data in a specified path. Just create a new temporary url with PUT method as argument.

$ ./swift-temp-url PUT 6000 /v1/AUTH_admin/container/uploadedfile thekey2
/v1/AUTH_admin/container/uploadedfile?temp_url_sig=d13a57b34e8da4b29b90e682cfe5af0187aaeea9&temp_url_expires=1374242636

$ curl -i -XPUT -d 'myuploadeddata' http://192.168.56.101:8080/v1/AUTH_admin/container/uploadedfile?temp_url_sig=d13a57b34e8da4b29b90e682cfe5af0187aaeea9\&temp_url_expires=1374242636
HTTP/1.1 201 Created
Last-Modified: Fri, 19 Jul 2013 12:24:51 GMT
Content-Length: 0
Etag: 73da0271131e15f1f02d5c0b3b14ca76
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx5ebb3ad8cd664153861f0-0051e93013
Date: Fri, 19 Jul 2013 12:24:51 GMT

In addition to GET and PUT verbs, once one of those are allowed we can perform a HEAD to retrieve header of the object.

$ curl -I -XHEAD http://192.168.56.101:8080/v1/AUTH_admin/container/openrc?temp_url_sig=12d78498a020a92b3a535b1ea7d99047ae84b3a4\&temp_url_expires=1374242076
HTTP/1.1 200 OK
Content-Length: 3083
Accept-Ranges: bytes
Last-Modified: Fri, 19 Jul 2013 11:46:55 GMT
Etag: fd310d3418adb42e9075a6192d6804c8
X-Timestamp: 1374234415.34971
Content-Type: application/octet-stream
X-Trans-Id: tx708b7df70eda4c10bc88d-0051e93a0f
Date: Fri, 19 Jul 2013 13:07:27 GMT

A service called Cloudwatt uses swift as object storage and as I have an account so I have tried the tempurl functionality. In Cloudwatt’s dashboard in account’s informations you’ll find your tenant id, username, password and the url of the identity service (example above are based on built-in identity service of swift) keystone.

First when getting stats from my account I seen that Cloudwatt has already set a meta Temp-Url-Key for me. Nice i’ll use it as it is.

$ swift --os-auth-url=https://identity.fr0.cloudwatt.com:443/v2.0 --os-username=fabien.boucher@enovance.com --os-password=******* --os-tenant-name=******* stat
Account: AUTH_e31d1c545b1943509f535a3803
Containers: 2
Objects: 161
Bytes: 148371033
Meta Temp-Url-Key: 824810b0-9217-11e2-9c16
X-Timestamp: 1363864042.26270
X-Trans-Id: tx40f6c3b3edef4e1c99f6550afab579ed
Content-Type: text/plain; charset=utf-8
Accept-Ranges: bytes

 

So I push a file on a container called ‘testcont’

$ swift --os-auth-url=https://identity.fr0.cloudwatt.com:443/v2.0 --os-username=fabien.boucher@enovance.com --os-password=******* --os-tenant-name=******* upload testcont openrc

 

With the swift-temp-url tool I can create the temporary url.

$ ./swift-temp-url GET 6000 /v1/AUTH_e31d1c545b1943509f535a3803be6f7e/testcont/openrc 824810b0-9217-11e2-9c16

 

Now I’m able to retrieve the file via the temporary url. Note that the hostname is not the same as above as here we use the storage url instead of keystone url.

$ curl https://storage.fr0.cloudwatt.com:443/v1/AUTH_e31d1c545b1943509f535a3803/testcont/openrc?temp_url_sig=65dd157a46c5a4ca5f606a1d3dc9851ccd5b3def\&temp_url_expires=1374341906

 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>