[−][src]Crate rowdy
Documentation: Stable | Master
rowdy
is a Rocket based JSON Web token based authentication server
based off Docker Registry's
authentication protocol.
Features
simple_authenticator
: A simple CSV based authenticatorldap_authenticator
: An LDAP based authenticator
By default, the simple_authenticator
feature is turned on.
rowdy
Authentication Flow
The authentication flow is inspired by Docker Registry authentication specification.
JSON Web Tokens
Authentication makes use of two types of JSON Web Tokens (JWT): Access and Refresh tokens.
Access Token
The access token is a short lived JWT that allows users to access resources within the scope that they are allowed to. The access token itself contains enough information for services to verify the user and their permissions in a stateless manner.
Refresh Token
The refresh token allows users to retrieve a new access token without needing to re-authenticate. As such, the refresh token is longer lived, but can be revoked.
Authentication Flow
- Client attempts to access a resource on a protected service.
- Service responds with a
401 Unauthorized
authentication challenge with information on how to authenticate provided in theWWW-Authenticate
response header. - Using the information from the previous step, the client authenticates with the authentication server. The client will receive, among other information, opaque access and refresh tokens.
- The client retries the original request with the Bearer token embedded in the request’s Authorization header.
- The service authorizes the client by validating the Bearer token and the claim set embedded within it and proceeds as usual.
Authentication Challenge
Services will challenge users who do not provide a valid token via the HTTP response
401 Unauthorized
. Details for
authentication is provided in the WWW-Authenticate
header.
Www-Authenticate: Bearer realm="https://www.auth.com",service="https://www.example.com",scope="all"
The realm
field indicates the authentcation server endpoint which clients should proceed to
authenticate against.
The service
field indicates the service
value that clients should use when attempting to
authenticate at realm
.
The scope
field indicates the scope
value that clients should use when attempting to
authenticate at realm
.
Retrieving an Access Token (and optionally Refresh Token) from the Authentication Server
A HTTP GET
request should be made to the realm
endpoint provided above. The endpoint will
support the following uery paremeters:
service
: The service that the client is authenticating for. This should be the same as theservice
value in the previous stepscope
: The scope that the client wishes to authenticate for. This should be the same as thescope
value in the previous step.offline_token
: Set totrue
if a refresh token is also required. Defaults tofalse
. Cannot be set totrue
when using a refresh token to retrieve a new access token.
When authenticating for the first time, clients should send the user's username and passwords
in the form of Basic
authentication. If the client already has a prior refresh token and
would like to obtain a new access token, the client should send the refresh token in the form
of Bearer
authentication.
If successful, the authentcation server will return a 200 OK
response with a
JSON body containing the following fields:
token
: An opaque Access (Bearer
) token that clients should supply to subsequent requests in theAuthorization
header.expires_in
: The duration in seconds since the token was issued that it will remain valid.issued_at
: RFC3339-serialized UTC standard time at which a given token was issued.refresh_token
: An opaqueRefresh
token which can be used to get additional access tokens for the same subject with different scopes. This token should be kept secure by the client and only sent to the authorization server which issues access tokens. This field will only be set whenoffline_token=true
is provided in the request.
If this fails, the server will return with the appropriate 4xx
response.
Using the Access Token
Once the client has a token, it will try the request again with the token placed in the HTTP Authorization header like so:
Authorization: Bearer <token>
Using the Refresh Token to Retrieve a New Access Token
When the client's Access token expires, and it has previously asked for a Refresh Token,
the client can make a GET
request to the same endpoint that the client used to retrieve the
access token (the realm
URL in an authentication challenge).
The steps are described in the section "Retrieving an Access Token" above. The process is the
same as the initial authentication except that instead of using Basic
authentication,
the client should instead send the refresh token retrieved prior as Bearer
authentication.
Also, offline_token
cannot be requested for when requesting for a new access token using a
refresh token. (HTTP 401 will be returned if this happens.)
Example
This example uses curl
to make request to the some (hypothetical) protected endpoint.
It requires jq
to parse JSON.
PROTECTED_RESOURCE="https://www.example.com/protected/resource/"
# Save the response headers of our first request to the endpoint to get the Www-Authenticate
# header
RESPONSE_HEADER=$(tempfile);
curl --dump-header "${RESPONSE_HEADER}" "${PROTECTED_RESOURCE}"
# Extract the realm, the service, and the scope from the Www-Authenticate header
WWWAUTH=$(cat "${RESPONSE_HEADER}" | grep "Www-Authenticate")
REALM=$(echo "${WWWAUTH}" | grep -o '\(realm\)="[^"]*"' | cut -d '"' -f 2)
SERVICE=$(echo "${WWWAUTH}" | grep -o '\(service\)="[^"]*"' | cut -d '"' -f 2)
SCOPE=$(echo "${WWWAUTH}" | grep -o '\(scope\)="[^"]*"' | cut -d '"' -f 2)
# Build the URL to query the auth server
AUTH_URL="${REALM}?service=${SERVICE}&scope=${SCOPE}&offline_token=true"
# Query the auth server to get a token -- replace the username and password
# below with the value from 1password
TOKEN=$(curl -s --user "mozart:password" "${AUTH_URL}")
# Get the access token from the JSON string: {"token": "...."}
ACCESS_TOKEN=$(echo ${TOKEN} | jq .token | tr -d '"')
# Query the resource again, but this time with a bearer token
curl -v -H "Authorization: Bearer ${ACCESS_TOKEN}" "${PROTECTED_RESOURCE}"
# Get the refresh token
REFRESH_TOKEN=$(echo "${TOKEN}" | jq .refresh_token | tr -d '"')
# Get a new access token
NEW_TOKEN=$(curl --header "Authorization: Bearer ${REFRESH_TOKEN}" "${AUTH_URL}")
# Parse the new access token
NEW_ACCESS_TOKEN=$(echo "${TOKEN}" | jq .token | tr -d '"')
# Query the resource again, but this time with a new access token
curl -v -H "Authorization: Bearer ${NEW_ACCESS_TOKEN}" "${PROTECTED_RESOURCE}"
Scope
Not in use at the moment. Just use all
.
Modules
auth | Authentication module, including traits for identity provider and |
serde_custom | Custom serde serialization and deserialization. |
token | Authentication token structs, and methods |
Macros
rocket_uri_macro_bad_request | Rocket code generated wrapping URI macro. |
rocket_uri_macro_ping | Rocket code generated wrapping URI macro. |
rocket_uri_macro_refresh_token | Rocket code generated wrapping URI macro. |
rocket_uri_macro_token_getter | Rocket code generated wrapping URI macro. |
Structs
Configuration | Application configuration. Usually deserialized from JSON for use. |
JsonMap | Represents a JSON key/value type. |
Url | Wrapper around |
Enums
ByteSequence | A sequence of bytes, either as an array of unsigned 8 bit integers, or a string which will be
treated as UTF-8.
This enum is (de)serialized |
Error | Top level error enum |
JsonValue | Represents any valid JSON value. |
Functions
launch | Convenience function to ignite and launch rowdy. This function will never return |
routes | Return routes provided by rowdy |