A custom http header to token claim mapper for Keycloak

At please-open.it we implement everything necessary for our customers’ use cases.

And one of our clients asked us: how to pass the locale when authenticating in “client_credentials”?

Use case

A custom application allows some admin users to change user’s password. A common use case, 2 possible approaches:

  • give “realm-admin” roles to those users. In some ways, restrict them with authorizations through “admin_fined_grained” feature in Keycloak
  • a custom third party application that checks authorizations (as well as other business constraints), and changes the user password through the Keycloak admin API.

What was the problem ?

the result of “PUT …/reset-password” contains an “error description” which is translated :

alt text

User locale selection

https://www.keycloak.org/docs/latest/server_admin/index.html#_user_locale_selection

  • “user selected”, “user profile” : impossible, we are in a “client_credentials” grant
  • “cient selected” : we need to change it depending on the user that wants to change the password
  • “cookie” : no cookie there
  • “Accepted language” : great ! Try to add “Accept-Language” during the authentication process.

It does not work, there is no “locale” defined.

Custom mapper

What we need is : get the “Accept-Language” header and put it in a claim “locale” in the access_token.

OIDCAttributeMapperHelper.mapClaim(accessToken, protocolMapperModel, keycloakSession.getContext().getHttpRequest().getHttpHeaders().getRequestHeader("Accept-Language").get(0));

(with checks before)

And it works :)

Usage

Just add this mapper to your client dedicated scopes (or in a scope) :

alt text

And now we have the correct messages depending on the locale :

Accept-Language: fr

{
    "error": "invalidPasswordMinLengthMessage",
    "error_description": "Mot de passe invalide : longueur minimale requise de 8."
}

Accept-Language: en

{
    "error": "invalidPasswordMinLengthMessage",
    "error_description": "Invalid password: minimum length 8."
}

Sources

https://github.com/please-openit/keycloak-http-header-token-mapper