Allows the creation of URLs to provide temporary access to objects. For example, a website may wish to provide a link to download a large object in OpenStack Object Storage, but the Object Storage account has no public access. The website can generate a URL that provides GET access for a limited time to the resource. When the web browser user clicks on the link, the browser downloads the object directly from Object Storage, eliminating the need for the website to act as a proxy for the request. If the user shares the link with all his friends, or accidentally posts it on a forum, the direct access is limited to the expiration time set when the website created the link.
A temporary URL is the typical URL associated with an object, with two additional query parameters:
temp_url_sig
A cryptographic signature
temp_url_expires
An expiration date, in Unix time
An example of a temporary URL:
https://swift-cluster.example.com/v1/AUTH_a422b2-91f3-2f46-74b7-d7c9e8958f5d30/container/object? temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& temp_url_expires=1323479485
To create temporary URLs, first set the X-Account-Meta-Temp-URL-Key
header on your Object Storage account to an arbitrary string. This string serves as a
secret key. For example, to set a key of
b3968d0207b54ece87cccc06515a89d4
using the
swift command-line tool:
$ swift post -m "Temp-URL-Key:b3968d0207b54ece87cccc06515a89d4
"
Next, generate an HMAC-SHA1 (RFC 2104) signature to specify:
Which HTTP method to allow (typically
GET
orPUT
)The expiry date as a Unix timestamp
The full path to the object
The secret key set as the
X-Account-Meta-Temp-URL-Key
Here is code generating the signature for a GET for 24
hours on
/v1/AUTH_account/container/object
:
import hmac from hashlib import sha1 from time import time method = 'GET' duration_in_seconds = 60*60*24 expires = int(time() + duration_in_seconds) path = '/v1/AUTH_a422b2-91f3-2f46-74b7-d7c9e8958f5d30/container/object' key = 'mykey' hmac_body = '%s\n%s\n%s' % (method, expires, path) sig = hmac.new(key, hmac_body, sha1).hexdigest() s = 'https://{host}/{path}?temp_url_sig={sig}&temp_url_expires={expires}' url = s.format(host='swift-cluster.example.com', path=path, sig=sig, expires=expires)
Any alteration of the resource path or query arguments results in a 401 Unauthorized error. Similarly, a PUT where GET was the allowed method returns a 401. HEAD is allowed if GET or PUT is allowed. Using this in combination with browser form post translation middleware could also allow direct-from-browser uploads to specific locations in Object Storage.
Note | |
---|---|
Changing the
|
Object Storage includes a script called swift-temp-url that generates the query parameters automatically:
$ bin/swift-temp-url GET 3600 /v1/AUTH_account/container/object mykey /v1/AUTH_account/container/object? temp_url_sig=5c4cc8886f36a9d0919d708ade98bf0cc71c9e91& temp_url_expires=1374497657
Because this command only returns the path, you must
prefix the Object Storage host name (for example,
https://swift-cluster.example.com
).
With GET Temporary URLs, a
Content-Disposition
header is set
on the response so that browsers interpret this as a file
attachment to be saved. The file name chosen is based on
the object name, but you can override this with a
filename
query parameter. The
following example specifies a filename of My
Test File.pdf
:
https://swift-cluster.example.com/v1/AUTH_a422b2-91f3-2f46-74b7-d7c9e8958f5d30/container/object? temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& temp_url_expires=1323479485& filename=My+Test+File.pdf
If you do not want the object to be downloaded, you can cause
Content-Disposition: inline
to be set on the response by adding
the inline
parameter to the query string, as follows:
https://swift-cluster.example.com/v1/AUTH_account/container/object? temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& temp_url_expires=1323479485&inline
To enable Temporary URL functionality, edit
/etc/swift/proxy-server.conf
to
add tempurl
to the
pipeline
variable defined in the
[pipeline:main]
section. The
tempurl
entry should appear
immediately before the authentication filters in the
pipeline, such as authtoken
,
tempauth
or
keystoneauth
. For
example:
[pipeline:main]
pipeline = pipeline = healthcheck cache tempurl authtoken keystoneauth proxy-server
Configuration option = Default value | Description |
---|---|
incoming_allow_headers =
|
Headers allowed as exceptions to incoming_remove_headers. Simply a whitespace delimited list of header names and names can optionally end with '*' to indicate a prefix match. |
incoming_remove_headers = x-timestamp |
Headers to remove from incoming requests. Simply a whitespace delimited list of header names and names can optionally end with '*' to indicate a prefix match. |
methods = GET HEAD PUT POST DELETE |
HTTP methods allowed with Temporary URLs |
outgoing_allow_headers = x-object-meta-public-* |
Headers allowed as exceptions to outgoing_allow_headers. Simply a whitespace delimited list of header names and names can optionally end with '*' to indicate a prefix match. |
outgoing_remove_headers = x-object-meta-* |
Headers to remove from outgoing responses. Simply a whitespace delimited list of header names and names can optionally end with '*' to indicate a prefix match. |
use = egg:swift#tempurl |
Entry point of paste.deploy in the server |