Troubleshooting
Authentication troubleshooting
User log in fails
-
Is there any error message shown on the login form?
-
Is the user enabled?
-
Are the user’s credentials correct?
-
Does the user (or an account linked to his identity) exist in the tenant / realm used?
-
Is HTTPS used? It is required to use HTTPS since version 1.16.0 to log into the UI.
-
Starting with version 1.15.0 Brute Force Detection is enabled, so in case the algorithm detects a brute force attempt it will temporarily disable the user.
-
When a user is temporarily locked and attempts to log in, the default Invalid username or password error message is displayed.
-
This message is the same error message as the message displayed for an invalid username or invalid password to ensure the attacker is unaware the account is disabled.
401 Unauthorized when using an API
-
Check the scope parameter for the token
-
Is the token issued for the right audience?
Client fails to get token, gets 401 unauthorized
Given access to the response: if it contains "invalid client credentials" in the body, you should check if correct client credentials are used.
-
Starting with Multitenant Access Control version 1.20, Keycloak started applying url-decoding to the client-id and client-secret for client authentication using basic authentication. This means that "invalid client credentials" can also be returned if the client-id or client-secret contain any of the following characters:
%
or+
. In this case appropriate actions need to be taken to change the client-id or client-secret to a valid value.
Only see exceptions / symptoms are observed:
-
Check logs of Nginx reverse proxy (or Ingress on cloud deployments). In the ELK-Stack you can search for "kubernetes.namespace: "<your-services-namespace>") or (kubernetes.namespace: "shared"" so see both your service’s and the reverse proxies logs. Typically, you’d see a response log from Keycloak with status code 401 and a reason like "invalid client credentials". If that’s the case, you should check if you configured your client credentials correctly.
Client fails to get token inside iframe, state is lost during the login flow
-
Please check what happens after the callback / redirection from the identity provider back to the application.
-
Normally the
state
query parameter from the URL is used to recover some state stored in a service-side session, browser session storage or cookie in order to then use thecode
query parameter to request a token from the token endpoint. -
Browsers started blocking cookies (and often also access to local and session storage) for third party websites inside iframes around 2020 and continue to become stricter.
-
This serves the purpose of protecting users from being tracked (ad networks, etc.), but obviously causes some challenges for portal applications and OAuth2 identity provider integrations.
-
If an origin is considered third party or not and what protection mechanisms are put in place varies from browser to browser.
-
It was observed that Firefox is a bit less strict than Chrome regarding this.
-
A typical scenario where this is encountered are modules that are hosted on a different origin than the portal (or developers loading views from localhost to test things).
-
Besides, using mechanism like redirects instead of hidden iframes to work around those constraints if possible, the only way around this is adapting the browser’s privacy settings accordingly. Typically this is called “cookie settings”, but affects local/session storage as well. In a business context, it is recommended to align with your IT department concerning managed browser settings.
-
Browser vendors are developing improved cookie handling approach, partitioning the cookie (and other things) by the respective enclosing third party page:
-
Chrome https://developers.google.com/privacy-sandbox/3pcd/chips (opt-in approach in trial in Chrome 100-103).
-
Firefox https://developer.mozilla.org/en-US/docs/Web/Privacy/State_Partitioning (default since Firefox 86 in strict privacy protection mode and since Firefox 90 in private browsing).
-
Token exchange fails with CORS / Cross-Origin Request Blocked: Same Origin Policy / Access-Control-Allow-Origin header missing
-
Multitenant Access Control sets appropriate headers to avoid this issues for your client. If you run into this issue, check the configured webOrigins of your client. A web origin is defined by scheme (protocol), host (domain), and port. Adding anything else will make it invalid.
Common mistakes:
-
Web Origin
-
adding more than a domain
OK
https://www.example.com https://www.example.com:42
Not OK
https://www.example.com/ https://www.example.com:42/ https://www.example.com/* https://www.example.com/foo
-
origin does not match your application’s origin (compare with the address bar of your browser)
-
-
scheme does not match (https vs http)
-
forgot to save the changes to client configuration?
-
Client used
-
for pure frontend login flow (no backend involved in authorization code flow) make sure to use the public client’s clientId (see form parameters of /token POST request)
-
-
Authorization troubleshooting
403 Forbidden when using an API
-
Is the API server’s client contained in the token aud (audience) claim? Hint: a client does not talk to itself, therefore the client itself will never be contained in the audience of its own tokens.
-
Is the token already expired?
-
Is the iss (issuer) claim correct? HTTP protocol and host should match the service’s configuration.
-
Does the related userinfo (either of the user or the service’s service principal) contain the required roles in the required format?
403 Forbidden + "CSRF token has been associated with this client"
-
Check your endpoint URL, this happens when the endpoint does not exist and falls back to the Web-UI (fallback for all request) including CSRF protection. Maybe your Multitenant Access Control version is too old?
-
Check your content-type header, for json data, make sure you are sending "application/json".