Access Token
The Access Token is defined by the OAuth2 specification.
An Access Token is a string representing an authorization issued to the client. In contrast to the ID Token, the string is usually opaque to the client.
Note that neither the OAuth2 or the OIDC specifications define any format for the token.
However, the OAuth2 specification does open for the token being handled as a by-reference or by-value token:
"The token may denote an identifier used to retrieve the authorization information or may self-contain the authorization information in a verifiable manner (i.e., a token string consisting of some data and a signature)."
This means that, according to the specifications, retrieving meta information about the Access Token can be done using the introspect endpoint or the token may be "self-contained" (by-value).
The Buypass implementation of the Access Token is is represented using JSON Web Token (JWT) (it is a by-value token). This means that the token can also easily be decoded locally. I fact the JSON object returned by the introspect is the same as for the JWT decoded Access Token, aside from the "active" claim/analysis.
Hence, it is up to the client to decide if it requires the use of the introspect endpoint (requesting token validation), or if it can do token decoding and validation locally.
Note that all Access Token claims (the inclusion and availability) are implementation specific (even though some claims may have have formal definitions/specifications).
Token lifespan
As a client does a request towards a service, it uses the Access Token to prove grant of access.
The most apparent reason for having short-lived Access Tokens is the fact that the longer the token lives, the higher the risk of compromise. In other words, if the Access Token somehow leaks (in a log, in the calling system or in the receiving service), the "window of opportunity" for an attacker increases with the token lifetime.
In addition, as the receiving service must validate the token, it can, since the token is an JSON Web Token (JWT) (by-value token), validated the token locally. There is no need to call the introspect endpoint to get the token claims/data or verify the signature. This is also recommended from a performance and stability viewpoint (not making the OpenID Provider part of processing each API request).
However, this also means that an Access Token can never be revoked (it can be revoked in the OpenID Provider, but the service will never pick this up unless it uses the introspect endpoint). Hence the specification states "Access Tokens might not be revocable by the Authorization Server. Access Token lifetimes SHOULD therefore be kept to single use or very short lifetimes."
To enable short lived Access tokens while keeping a acceptable user experience, the use of Refresh Token should be considered.
Claims
Access Tokens can be represent the combination of a client and an end-user, or a client only.
It is important to notice that neither the OAuth2 or the OIDC specifications define any format for the Access Token (this is also the case for the return values of the introspect endpoint).
As a consequence, the claims provided in the tokens are to be considered Buypass and implementation specific. Buypass will strive to use the standard claims (with values according to the definition) whenever possible.
The Access Token may contain both "standard"/basic claims, extended claims and custom claims (depending on the client configuration, the scopes requested and the Security Domain). Buypass custom claims will be named with prefix "bp_" (according to Private Claim Names). The token might also contain implementation specific claims that are a consequence of the server implementation libraries.
Code Flow Access Token
The Access Token resulting from a Authorization Code Flow authentication references both the client and the end-user. The table below lists "standard"/basic claims.
Claim | Description | Example |
---|---|---|
jti | JWT ID. A unique identifier for the token, which can be used to prevent reuse of the token. See jti claim. | "jti": "44fc62b6-890a-4a0e-8754-6455d8968294" |
exp | Expiration time on or after which the Access Token MUST NOT be accepted for processing. Epoc time format. | "exp": 1525438143 |
nbf | Identifies the time before which the JWT must not be accepted for processing. | "nbf": 0 |
iat | Time at which the JWT was issued. Epoc time format. | "iat": 1525437843 |
iss | The Buypass ID Provider instance. The issuer of the token. | "iss": "https://auth.buypass.no/auth/realms/SECURITYDOMAIN" |
sub | The subject identifier. A locally unique and never reassigned identifier within the Issuer for the end-user. Intended to be consumed by the client as a possible end-user reference. NOTE: Even if the identifier is "never reassigned" it may still change for the same user! A user may be reassigned a new sub, but a used sub will never be assigned to a new user. Hence, do not use this as a user reference over time! | "sub": "7a9cb1cf-c495-4db1-a25e-d24d84accc6d" |
typ | Implementation specific claim denoting the token type. Not to be used by clients! | "typ": "Bearer" |
azp | Authorized party - the party to which the Access Token was issued. If present, will contain the client_id of the party. | "azp": "oidc-client" |
nonce | Case sensitive string value used to associate a client session with an Access Token, and to mitigate replay attacks. The value is passed through unmodified from the authentication request to the Access Token. | "nonce": "681913a288be" |
auth_time | Time when the client authentication occurred. | "auth_time": 0 |
session_state | Implementation specific claim for use with session handling. Not to be used by clients! | "session_state": "904cbda8-1e2f-4e90-a7e6-1606aa7c622b" |
acr | String specifying an Authentication Context Class Reference value that identifies the Authentication Context Class that the authentication performed satisfied. This can for example be values based on some definition of Level of Assurance (LoA). | "acr": "4" |
scope | List of scopes approved by the OpenID Provider for this Access Token. Note that the list of scopes might be different from what the client initially requested. Some scopes may not be approved by the OpenID Provider, and some additional scopes may have been added as being configured as default scopes for the client. | "scope": "openid profile bpid email" |
Example basic token
Only the "openid" scope is requested.
{ "jti": "9d85933d-5e20-4f2d-ae32-64c384d33e15", "exp": 1558703627, "nbf": 0, "iat": 1558703567, "iss": "https://auth.test.buypass.no/auth/realms/SECURITYDOMAIN", "sub": "d6cccb1c-4390-41c1-b956-184ac9213a64", "typ": "Bearer", "azp": "oidc-client", "auth_time": 0, "session_state": "15f6a556-fd6e-46a3-b2b8-e2b9511b3ee4", "acr": "1", "scope": "openid" }
Example extended token
In addition to the "openid" scope, the scopes "profile, bpid and bpnnin" are requested.
{ "jti": "5f5a1188-88fa-4c88-a361-2c99008527fd", "exp": 1558703827, "nbf": 0, "iat": 1558703767, "iss": "https://auth.test.buypass.no/auth/realms/SECURITYDOMAIN", "sub": "f:6ba131e6-fce2-4a92-924b-26b47a5632c1:15089100213", "typ": "Bearer", "azp": "oidc-client", "nonce": "0eQKh14zYgXrdLg1pSkcyHnVX4GiW4ztjgyHlPzayWY", "auth_time": 1558703767, "session_state": "92f817ea-190d-47e5-a323-44f4c2967ebe", "acr": "1", "scope": "openid bpnnin bpid profile", "name": "BRITT FOS EDLAND", "preferred_username": "15089100213", "bp_id_sub": "101430957", "given_name": "BRITT FOS", "family_name": "EDLAND", "bp_nnin_sub": "15089100213" }
Client Credentials Access Token
The Access Token resulting from a Client Credentials authentication has no reference to an end-user, and is issued to the client only. The table below lists "standard"/basic claims.
Claim | Description | Example |
---|---|---|
jti | JWT ID. A unique identifier for the token, which can be used to prevent reuse of the token. See jti claim. | "jti": "44fc62b6-890a-4a0e-8754-6455d8968294" |
exp | Expiration time on or after which the Access Token MUST NOT be accepted for processing. Epoc time format. | "exp": 1525438143 |
nbf | Identifies the time before which the JWT must not be accepted for processing. | "nbf": 0 |
iat | Time at which the JWT was issued. Epoc time format. | "iat": 1525437843 |
iss | The Buypass ID Provider instance. The issuer of the token. | "iss": "https://auth.buypass.no/auth/realms/SECURITYDOMAIN" |
sub | The subject identifier. A locally unique and never reassigned identifier within the Issuer for the client. Intended to be consumed by a service as a possible client reference. NOTE: Even if the identifier is "never reassigned" it may still change for the same client! A client may be reassigned a new sub, but a used sub will never be assigned to a new client. Hence, do not use this as a client reference over time! | "sub": "3bdc7a83-eb38-4610-8263-216526fde553" |
typ | Implementation specific claim denoting the token type. Not to be used by clients! | "typ": "Bearer" |
azp | Authorized party - the party to which the Access Token was issued. If present, will contain the client_id of the party. | "azp": "oidc-client" |
auth_time | Time when the client authentication occurred. | "auth_time": 0 |
session_state | Implementation specific claim for use with session handling. Not to be used by clients! | "session_state": "42197ec8-af93-426e-a858-511c5a01c9d7" |
acr | String specifying an Authentication Context Class Reference value that identifies the Authentication Context Class that the authentication performed satisfied. This can for example be values based on some definition of Level of Assurance (LoA). | "acr": "1" |
scope | List of scopes approved by the OpenID Provider for this Access Token. Note that the list of scopes might be different from what the client initially requested. Some scopes may not be approved by the OpenID Provider and some additional scopes may have been added as being configured as default scopes for the client. | "scope": "profile email service-api" |
Example basic token
Authentication request
BASEURL="https://auth.test12.buypass.no/auth/realms/SECURITYDOMAIN/protocol/openid-connect"; CLIENT_ID="oidc-client" CLIENT_SECRET="mysecret" BASIC_AUTH=`echo -n "${CLIENT_ID}:${CLIENT_SECRET}"| base64` SCOPE="service-api" curl -i -w "\n" \ -H "Content-Type: application/x-www-form-urlencoded" \ -H "Authorization: Basic ${BASIC_AUTH}" \ -X POST "${BASEURL}/token" \ -d "grant_type=client_credentials"\ "&scope=${SCOPE}"
Basic token
{ "jti": "b6d8edea-0261-4c78-b1c2-3ed4f44e6373", "exp": 1558607713, "nbf": 0, "iat": 1558607653, "iss": "https://auth.test.buypass.no/auth/realms/SECURITYDOMAIN", "sub": "3bdc7a83-eb38-4610-8263-216526fde553", "typ": "Bearer", "azp": "oidc-client", "auth_time": 0, "session_state": "e24dcbc4-2ffe-4f8e-b701-e9c97ecebd39", "acr": "1", "scope": "service-api", }