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 Swift, but the Swift account has no public access. The website can generate a URL that will provide GET access for a limited time to the resource. When the web browser user clicks on the link, the browser will download the object directly from Swift, obviating the need for the website to act as a proxy for the request. If the user were to share the link with all his friends, or accidentally post it on a forum, the direct access would be 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 Swift account to an arbitrary string. This string
will serve 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 Swift. Note that
Note | |
---|---|
Changing the
|
Swift includes a script called swift-temp-url that will generate 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
Swift storage hostname (for example,
https://swift-cluster.example.com
).
With GET Temporary URLs, a
Content-Disposition
header will be
set on the response so that browsers will interpret this
as a file attachment to be saved. The filename 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
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 |
use=egg:swift#tempurl | Entry point of paste.deploy in the server. You should not ever need to change this. |
methods=GET HEAD PUT | HTTP methods allowed with Temporary URLs |
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. |
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. |
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. |
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. |