Tokens
The EMu REST API uses Java Web Tokens (JWT) for authentication. Each request supplies an encoded JWT as a Bearer token in the HTTP Authorization header. When a request is received the token is extracted and checked to ensure it is valid, that is it was issued by the shim and has not expired. The only request not checked is POST /{tenant}/tokens as it is used to generate a token. Tokens have an expiry time associated with them. The expiry time is defined on a per tenant basis and is the timeout property found in the tenant’s settings in the restapi/conf/tenants.conf
file. A typical expiry time is 30 minutes. The expiry time for a token is reset each time the token is used with a valid request. Hence the expiry time is the number of minutes that the token is not used before it is invalid. Think of it as an idle timeout. Once a token’s expiry time is reached the token is removed from the shim.
The JSON below shows the information available about a token:
{
"id": "emu:/museum/tokens/ca343114-7aa2-45a5-b3cf-9cfb1213a84e",
"version": 1,
"data": {
"iat": 1619581725,
"exp": 1619605035,
"iss": "emu:/shared/tenants/museum",
"sub": "emu:/museum/users/barney",
"gid": "emu:/museum/roles/Admin",
"jti": "emu:/museum/tokens/ca343114-7aa2-45a5-b3cf-9cfb1213a84e",
"lid": "en_GB",
"wfg": [
"Admin",
"Conservation",
"Archives"
]
}
}
A token (JWT) has the following fields defined:
Name | Description |
---|---|
iss | Token issuer. The issuer is a URI identifying the tenant associated with the token. |
exp | Token expiry time. A value representing the number of seconds from 1/1/1970 at which the token expires. Once the expiry date passes the token is no longer valid. |
iat | Time at which the token was issues. The value is interpreted the same as that for exp. |
sub | Token’s subject. The subject is a URI identifying the user associated with the token. |
gid | Token’s group. The group is a URI identifying the role associated with the token. |
jti | Token’s unique identifier. The identifier is a URI that can be used to retrieve the token. |
lid | Token’s locale. The locale to use for error messages generated when this token is used. |
wfg | Token’s workflow groups. A JSON array containing a list of groups associated with the token. |
The following requests are available for the tokens resource.
Create
POST /{tenant}/tokens
The POST method creates a token. A token must pass in either a username/password combination or an OpenID Connect token for authentication. If a username/password is sent then the EMu server will authenticate the credentials against the texpress PAM service. The service can be configured to use a number of different authentication sub-systems (e.g. AD, NIS, passwd file, LDAP, etc). If an OpenID Connect token is sent then the EMu server will contact the token’s issuing server to validate it. If validation succeeds then a JWT token is generated for use with the shim.
If a username/password are used then the request payload should contain:
{
"username": "{username}",
"password": "{password}"
}
If an OpenID Connect token is used then the request payload should contain:
{
"token": "{token}"
}
If the request is successful then a 201
status is returned and the payload contains the token information. The Location: header contains a URL used to retrieve the token and the Authorization: header contains the encoded token itself.
Example URI
POST /museum/tokens
Headers
Content-Type: application/json
Prefer: representation=minimal
Response 201
{
"id": "emu:/museum/tokens/65955134-39d7-4041-b4a3-b32aaec0d65c",
"version": 1,
"data": {
"iat": 1620004860,
"exp": 1620005760,
"iss": {
"id": "emu:/shared/tenants/museum",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/shared/tenants/museum"
}
}
},
"sub": {
"id": "emu:/museum/users/emu",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/users/emu"
}
}
},
"gid": {
"id": "emu:/museum/roles/Admin",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/roles/Admin"
}
}
},
"jti": {
"id": "emu:/museum/tokens/65955134-39d7-4041-b4a3-b32aaec0d65c",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens/65955134-39d7-4041-b4a3-b32aaec0d65c"
}
}
},
"lid": "en_GB",
"wfg": [
"Admin"
]
},
"@namespaces": {
"emu": {
"name": "http://axiell.com/emu#"
}
},
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens/65955134-39d7-4041-b4a3-b32aaec0d65c"
},
"start": {
"method": "GET",
"href": "http://swanston.melbourne.axiell.com:8084/"
},
"emu:create": {
"method": "POST",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens",
"isHrefTemplate": true,
"encoding": "json",
"schemaUrl": "http://swanston.melbourne.axiell.com:8084/museum/resources/tokens"
},
"search": {
"method": "GET",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens"
},
"emu:update": {
"method": "PATCH",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens/65955134-39d7-4041-b4a3-b32aaec0d65c",
"encoding": "json",
"schemaUrl": "http://json.schemastore.org/json-patch"
},
"emu:update-all": {
"method": "PATCH",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens",
"encoding": "json",
"schemaUrl": "http://json.schemastore.org/json-patch"
},
"emu:delete": {
"method": "DELETE",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens/65955134-39d7-4041-b4a3-b32aaec0d65c"
},
"emu:delete-all": {
"method": "DELETE",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens"
}
}
}
Response Headers
Content-Type: application/vnd.mason+json; charset=UTF-8
Location: http://swanston.melbourne.axiell.com:8084/museum/tokens/d334ee4d-d4e2-4465-99f0-bbf1aa9bacc5
Authorization: Bearer {token}
Delete
DELETE /{tenant}/tokens
DELETE /{tenant}/tokens/{id}
The DELETE method removes a token from the shim. It effectively logs out the user associated with the token. The first form will delete all tokens created by the user making the request. If the requesting user is the admin account then all tokens for the given {tenant} are removed, hence logging out all users of the tenant. The second form removes a single token identified by its unique identifier.
If the token(s) are successfully deleted then a 200
status is returned. The payload will contain the deleted token(s). For the first form a JSON matches array will contain the deleted tokens, while for the second form a single token is returned.
Example URI
DELETE /museum/tokens
Headers
Authorization: Bearer {token}
Prefer: representation=minimal
Response 200
{
"@namespaces": {
"emu": {
"name": "http://axiell.com/emu#"
}
},
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens"
},
"start": {
"method": "GET",
"href": "http://swanston.melbourne.axiell.com:8084/"
},
"emu:create": {
"method": "POST",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens",
"isHrefTemplate": true,
"encoding": "json",
"schemaUrl": "http://swanston.melbourne.axiell.com:8084/museum/resources/tokens"
},
"search": {
"method": "GET",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens"
},
"emu:delete-all": {
"method": "DELETE",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens"
},
"emu:update-all": {
"method": "PATCH",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens",
"encoding": "json",
"schemaUrl": "http://json.schemastore.org/json-patch"
}
},
"matches": [
{
"id": "emu:/museum/tokens/65955134-39d7-4041-b4a3-b32aaec0d65c",
"version": 1,
"data": {
"iat": 1620004860,
"exp": 1620005783,
"iss": {
"id": "emu:/shared/tenants/museum",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/shared/tenants/museum"
}
}
},
"sub": {
"id": "emu:/museum/users/emu",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/users/emu"
}
}
},
"gid": {
"id": "emu:/museum/roles/Admin",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/roles/Admin"
}
}
},
"jti": {
"id": "emu:/museum/tokens/65955134-39d7-4041-b4a3-b32aaec0d65c",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens/65955134-39d7-4041-b4a3-b32aaec0d65c"
}
}
},
"lid": "en_GB",
"wfg": [
"Admin"
]
},
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens/65955134-39d7-4041-b4a3-b32aaec0d65c"
}
}
}
]
}
Response Headers
Content-Type: application/vnd.mason+json; charset=UTF-8
Authorization: Bearer {token}
Update
PATCH /{tenant}/tokens
PATCH /{tenant}/tokens/{id}
The PATCH method updates the expiry time on a token(s). It is similar to the UNIX touch command in that it updates the expiry time on the shim’s version of the token, forcing the token to still be valid. The first form will reset the expiry time for all tokens owned by the user making the request. If the shim admin account requests the update then all the tenant’s tokens are updated. The second form allows an individual token, owned by the user, to be updated.
While a token remains valid on the server the user may use it, even if the client program sends a token that has exceeded its expiry date. The mechanism allows for a third party to refresh tokens without the client receiving the updated token for use.
The payload must be empty for both forms of the request.
A 200
status is returned if the updates succeed. The payload will consist of the tokens updated.
Example URI
PATCH /museum/tokens
Headers
Authorization: Bearer {token}
Prefer: representation=minimal
Response 200
{
"@namespaces": {
"emu": {
"name": "http://axiell.com/emu#"
}
},
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens"
},
"start": {
"method": "GET",
"href": "http://swanston.melbourne.axiell.com:8084/"
},
"emu:create": {
"method": "POST",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens",
"isHrefTemplate": true,
"encoding": "json",
"schemaUrl": "http://swanston.melbourne.axiell.com:8084/museum/resources/tokens"
},
"search": {
"method": "GET",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens"
},
"emu:delete-all": {
"method": "DELETE",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens"
},
"emu:update-all": {
"method": "PATCH",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens",
"encoding": "json",
"schemaUrl": "http://json.schemastore.org/json-patch"
}
},
"matches": [
{
"id": "emu:/museum/tokens/550e9f0d-017a-4b3f-8931-0e8c670c24ff",
"version": 1,
"data": {
"iat": 1620006482,
"exp": 1620007395,
"iss": {
"id": "emu:/shared/tenants/museum",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/shared/tenants/museum"
}
}
},
"sub": {
"id": "emu:/museum/users/emu",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/users/emu"
}
}
},
"gid": {
"id": "emu:/museum/roles/Admin",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/roles/Admin"
}
}
},
"jti": {
"id": "emu:/museum/tokens/550e9f0d-017a-4b3f-8931-0e8c670c24ff",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens/550e9f0d-017a-4b3f-8931-0e8c670c24ff"
}
}
},
"lid": "en_GB",
"wfg": [
"Admin"
]
},
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens/550e9f0d-017a-4b3f-8931-0e8c670c24ff"
}
}
}
]
}
Response Headers
Content-Type: application/vnd.mason+json; charset=UTF-8
Authorization: Bearer {token}
Retrieve
GET /{tenant}/tokens[?select={selectlist}]
GET /{tenant}/tokens/{id}[?select={selectlist}]
The GET method retrieves the token(s) associated with the requested tenant. The first form retrieves all tokens owned by the requesting user, unless the admin account is used in which case all tokens are returned. The second form allows a single token to be retrieved, provided the requester owns the token or the admin account is used.
By default all values in the record are returned. You can limit the values returned using the select query parameter. The parameter takes a comma separated list of field names. The field names are that of the enveloped record so most field names will start with data.. The Select Syntax section provides a complete description of acceptable values for the select query parameter.
Example URI
GET /museum/tokens
Headers
Authorization: Bearer {token}
Prefer: representation=minimal
Response 200
{
"@namespaces": {
"emu": {
"name": "http://axiell.com/emu#"
}
},
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens"
},
"start": {
"method": "GET",
"href": "http://swanston.melbourne.axiell.com:8084/"
},
"emu:create": {
"method": "POST",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens",
"isHrefTemplate": true,
"encoding": "json",
"schemaUrl": "http://swanston.melbourne.axiell.com:8084/museum/resources/tokens"
},
"search": {
"method": "GET",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens"
},
"emu:delete-all": {
"method": "DELETE",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens"
},
"emu:update-all": {
"method": "PATCH",
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens",
"encoding": "json",
"schemaUrl": "http://json.schemastore.org/json-patch"
}
},
"matches": [
{
"id": "emu:/museum/tokens/550e9f0d-017a-4b3f-8931-0e8c670c24ff",
"version": 1,
"data": {
"iat": 1620006482,
"exp": 1620007395,
"iss": {
"id": "emu:/shared/tenants/museum",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/shared/tenants/museum"
}
}
},
"sub": {
"id": "emu:/museum/users/emu",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/users/emu"
}
}
},
"gid": {
"id": "emu:/museum/roles/Admin",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/roles/Admin"
}
}
},
"jti": {
"id": "emu:/museum/tokens/550e9f0d-017a-4b3f-8931-0e8c670c24ff",
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens/550e9f0d-017a-4b3f-8931-0e8c670c24ff"
}
}
},
"lid": "en_GB",
"wfg": [
"Admin"
]
},
"@controls": {
"self": {
"href": "http://swanston.melbourne.axiell.com:8084/museum/tokens/550e9f0d-017a-4b3f-8931-0e8c670c24ff"
}
}
}
]
}
Response Headers
Content-Type: application/vnd.mason+json; charset=UTF-8
Authorization: Bearer {token}