Authentication and Authorization¶
Any Swift authentication/authorization middleware must follow the protocols of Keystone, the official OpenStack identity service. If you decide to use the Keystone Swift auth middleware, all versions of the auth protocol will be supported. (Currently, Keystone has three versions of their protocol.) If you choose another auth system, it may only support a subset of those protocol versions.
The SwiftStack Auth middleware supports three versions of the auth protocol, known as "V1 Auth", "V2 Auth", and "V3 Auth".
V1 Auth¶
- For a user to authenticate to a cluster, they must know three pieces of information:
- Username
- Password
- AUTH_URL (displayed on the Cluster Monitor page)
The user will provide the information using one of two commands, swift or curl, and they will get information about their Swift account in return. Two key pieces of information returned are the AUTH_TOKEN
and STORAGE_URL
.
In the examples shown, the user provides "superman" for both the username and password.
Authentication via swift command
swift -A <AUTH_URL> -U <USERNAME> -K <PASSWORD> stat -v
It returns several pieces of information, including the AUTH_TOKEN
and STORAGE_URL
.
$ swift -A http://swift.example.com/auth/v1.0 -U superman -K superman \
stat -v
StorageURL: http://swift.example.com/v1/AUTH_superman
Auth Token: AUTH_tkb5bab9e25a274b4a853fe2587b5dc8f9
Account: AUTH_superman
Containers: 0
Objects: 0
Bytes: 0
Content-Type: text/plain; charset=utf-8
X-Timestamp: 1375225766.50237
X-Trans-Id: tx88ac2ec242fd4af6a1e3d-0051f847a6
X-Put-Timestamp: 1375225766.50237
Authentication via curl command
curl -i -H "X-Auth-User: <USERNAME>" -H "X-Auth-Key: <PASSWORD>" <AUTH_URL>
It returns several pieces of information, including the AUTH_TOKEN
and STORAGE_URL
.
Tip
Under SwiftStack Auth, the storage URL always ends in a Swift Storage Account name that starts with AUTH_ followed by the username.
$ curl -i -H "X-Auth-User: superman" -H "X-Auth-Key: superman" \
https://swift.example.com/auth/v1.0/
HTTP/1.1 200 OK
X-Storage-Url: https://swift.example.com/v1/AUTH_superman
X-Auth-Token: AUTH_tke43b35e50eab4eecaf72221dc8f2f3a7
Content-Type: text/html; charset=UTF-8
X-Storage-Token: AUTH_tke43b35e50eab4eecaf72221dc8f2f3a7
X-Trans-Id: txe66f5a0dde8c41be9c487-0051f2f216
Content-Length: 0
Date: Fri, 26 Jul 2013 22:03:02 GMT
V2 Auth¶
Just like V1 Auth, three pieces of information are required for a user to authenticate to a cluster:
- Username
- Password
- AUTH_URL (same as the V1 Auth URL from the Cluster Monitor page except the
v1.0
at the end is replaced withv2.0
, for example,http://swift.example.com/auth/v2.0
)
However, unlike V1 Auth, there is an additional item which can be provided:
the tenant, which is a general Keystone concept which means
account in the specific case of Swift. The tenant affects which storage
URL you will get back in the response to your auth request. If you don't
specify a tenant, you will get the default storage URL for your username, as
in V1 Auth. For example, if your username is alice
and your auth
middleware uses the default prefix of AUTH_
, then your default
account name is AUTH_alice
, and you will get back a storage URL of the
form https://swift.example.com/v1/AUTH_alice
.
However, what if Alice wants to view data in Bob's account, assuming that
Bob has given her access via a container ACL or account ACL? (See
Container ACLs and Account ACLs.) Or what if
the Swift cluster has been set up so that users don't each get their own
accounts, but rather share project-based accounts such as AUTH_project1
?
Using V1 Auth, Alice (or a tool she uses) must manually examine the returned
storage URL, remove her account's name, and append the name of the account
she wants to access. (This tends to work in practice, but it is not
guaranteed -- the other account might be accessed via a different server,
for instance!) However, V2 Auth allows her to get the correct storage
URL directly, by providing as input the tenant (account) that she is
interested in accessing. Typical tenants might include AUTH_alice
(to
access her own account) or AUTH_shared
(to access a shared account) or
LDAP_bob
(to access Bob's account, which is authenticated via LDAP).
Authentication via "swift" command
The swift
command uses different command-line flags to specify V2 Auth
params. To specify that you want to use the V2 Auth protocol, use a command
line such as the following:
swift --os-auth-url <AUTH_URL> \
--os-username <USERNAME> \
--os-password <PASSWORD> \
--os-tenant-name <TENANT> \
stat -v
Alternatively, if you will be invoking the swift
command several times and
want to save some typing, you can store the input parameters in environment
varables:
export OS_USERNAME=<username>
export OS_PASSWORD=<password>
export OS_TENANT_NAME=<tenant>
export OS_AUTH_URL=<auth_url>
swift stat -v
The output will be exactly the same as for V1 Auth.
Authentication via curl command
Where V1 Auth uses HTTP headers in a GET command, V2 Auth uses a POST command with JSON containing the credentials as the request body. Since it's easy to make a typo such as missing or misplacing a closing brace, we recommend that if you use raw curl commands for V2 Auth requests, you put your input in a file.
The format of the JSON object containing the credentials is as follows:
{
"auth" : {
"passwordCredentials" : {
"username" : "<username>",
"password" : "<password>"
},
"tenantName" : "<tenant>"
}
}
If the above text is stored in a file named /tmp/creds
, then you can
authenticate with the V2 Auth protocol using the following curl command:
curl -i <AUTH_URL> -d @/tmp/creds
This will return a blob of valid JSON, but it is difficult to read because
of its lack of formatting. To see a nicely-formatted version of the auth
response, use a formatter such as json_pp
:
curl -s <AUTH_URL> -d @/tmp/creds | json_pp
Since json_pp
requires valid JSON as input, you must use the -s
flag
with curl to suppress the HTTP headers. However, this means that you won't
see the HTTP return code, and it will not be obvious whether the auth
request succeeded. Specifically, the response body for an invalid auth
request is the string "Invalid credentials", which is not valid JSON, so
a program such as json_pp
will throw an error when trying to format it.
With this in mind, the output of a successful V2 auth request looks like this:
{
"access" : {
"token" : {
"id" : "AUTH_tk4602560647c640de86924e2f28716b46"
"expires" : "2015-01-22T00:04:06Z",
"tenant" : {
"id" : "AUTH_sharedacct",
"name" : "AUTH_sharedacct"
},
},
"user" : {
"name" : "alice",
"id" : "alice"
"roles" : [
{
"id" : "alice",
"name" : "alice"
},
{
"name" : "AUTH_alice",
"id" : "AUTH_alice"
},
{
"name" : ".reseller_admin",
"id" : ".reseller_admin"
}
],
},
"serviceCatalog" : [
{
"endpoints" : [
{
"region" : "default",
"publicURL" : "http://192.168.22.200/v1/AUTH_sharedacct",
"versionId" : 1,
"tenantId" : "AUTH_sharedacct"
},
{
"publicURL" : "http://192.168.22.200/v1/AUTH_alice",
"region" : "default",
"tenantId" : "AUTH_alice",
"versionId" : 1
}
],
"name" : "Swift Object Storage (http://192.168.22.200)",
"type" : "object-store"
}
]
}
}
V3 Auth¶
SwiftStackAuth also accepts and responds to Keystone V3 API requests. Because all SwiftStackAuth really cares about is a username and password, there are some differences in behavior between SwiftStackAuth and Keystone when using the Keystone V3 API.
Any Keystone object that has an ID and a name will always have those two values equal to each other in the response. The value in the response will be, in order of preference, the ID given in the request, the name given in the request, or a dummy value if neither an ID nor name was present in the request.
There is no "scoping" of tokens in SwiftStackAuth, but SwiftStackAuth will try to deliver a response that a Keystone V3 API client will expect. Any client that tries to use more of the Keystone V3 API than simply getting tokens will probably not work.
See the Keystone V3 API documentation for more details on getting tokens using the Keystone V3 API.