How to get and handle tokens
Different kinds of tokens can be issued by Multitenant Access Control:
- Access token
-
Token giving the bearer the privilege to access protected resources. This token does not necessarily need to be a JWT, it is opaque. Validation is explicitly done by calling the OAuth 2.0 Introspect endpoint or implicitly done by calling the OAuth 2.0 Userinfo endpoint.
- Refresh token
-
Can be used to obtain a new access token while valid without repeating the full login flow.
- ID token
-
See OpenID ID token explanation. It contains information about the user in the form of a JSON Web Tokens (JWT). A JWT is a Base64 encoded JSON data structure containing a signature. Its consistency can thus be verified using the related public key provided (e.g. via JWK Set) by the authorization server that generated the token.
To find out what is the content of a JWT, it can be pasted into tools similar to JWT.io.
Be aware that JWT.io is a public service and the token might be logged and misused.
Single audience principle
The scope of a token request tells Multitenant Access Control what the token will be used for. To prevent token misuse by the recipients of access tokens, a token’s audience is always just a single application (represented by the application id). This is called "single audience" concept.
An empty scope parameter will not be accepted when requesting a token. |
For the user tokens, the scope is strictly bound to the application that was used to perform the login flow. Because of single sign-on, the user will not be aware that every module UI has to obtain a new token within its specific scope.
The scope parameter value has to be of the form "aud:<targetSystemClientId>", e.g. aud:macma. In order to let applications check your roles and privileges by calling the userinfo-endpoint, the scope also has to include the value openid . Multiple scopes must be separated by spaces.
|
Obtaining a token
In order for your UI or backend to obtain a token from Multitenant Access Control, it needs to send a POST request to the token endpoint according to OpenID Connect. The request and its parameters are documented in our API documentation.
We strongly recommend using a library for handling the whole OAuth flow. It abstracts the process and endpoints for you and is kept up-to-date when the standard (or its implementation) change. https://oauth.net/code/ has a neat compilation of all implementations sorted by programming language.
Don’t request a token for every request to avoid heavy load. You can use the same token for every call to the same module until expired. |
Token refresh / renewal
Typically, access tokens were refreshed in web applications using silent renewal (authorization code flow with PKCE in a hidden iframe with parameter "prompt=none"). The same goes for checking for an active single sign-on session upon opening the application.
Modern browsers started blocking third party apps from setting cookies since around 2020 to block tracking and improve privacy. Unfortunately that also affects the hidden iframe approach. Furthermore, popups can typically not be opened without user interaction to block unwanted popups.
The approach using the refresh token is unaffected. For using silent renew / silent login via hidden iframes, third party cookies from the authorization server’s host have to be allowed in the user’s browser.
See also Keycloak’s writeup on the topic of modern browsers and tracking protection at Keycloak: Modern Browsers with Tracking Protection and IBM: Cross Origin Session Detection.
Token Security
Please consider:
-
Tokens are not protected by misuse from other applications on the same origin.
-
Cookies: Your CSRF protection may not safeguard against misuse by other applications on the same host name.
-
Browser Storage: Other application can access the storage on the same origin.
-
Other applications on the same host name might be put at risk by vulnerabilities in your application.
-
You have to namespace your cookie / storage properly to avoid conflicts if multiple log-ins are executed from the same origin.
Therefore, we strongly recommend running your application on a dedicated domain or subdomain.