19

I need to create a Protocol Mapper of type Script Mapper in Keycloak. The script should get a user attribute, check its size, and put it on the token. I found no documentation or examples of how a script should be created. From the bits and pieces I could gather, I guess I the script would need to look something like:

var value = user.getAttribute("myAttribute");
if (value.length > LIMIT) {
    value = value.substring(0,LIMIT);
}
token.setOtherClaims("myAttribute",value);
  • Is this right? I made up user.getAttribute("myAttribute"). Is there a source of documentation where I can find how to get a Keycloak user attribute?
  • does the script need to return anything? Any help would be mostly welcome.
Jacobs2000
  • 856
  • 2
  • 15
  • 25

2 Answers2

39

The magic of Script Mappers can be understood by looking at the keycloak sources here: Source

The script can return something by using the exports variable like this

exports = "Claim Value"

The different types:

Here is an example script:

// you can set standard fields in token
token.setAcr("test value");

// you can set claims in the token
token.getOtherClaims().put("claimName", "claim value");

// multi-valued claim (thanks to @ErwinRooijakkers)
token.getOtherClaims().put('foo', Java.to(['bars'], "java.lang.String[]"))

// work with variables and return multivalued token value
var ArrayList = Java.type("java.util.ArrayList");
var roles = new ArrayList();
var client = keycloakSession.getContext().getClient();
var forEach = Array.prototype.forEach;
forEach.call(user.getClientRoleMappings(client).toArray(), function(roleModel) {
  roles.add(roleModel.getName());
});

exports = roles;

Hope it helps!

André B.
  • 669
  • 5
  • 8
11

I needed this feature but could not find this "script mapper" thing in my freshly installed 10.0.2. Turns out it is not enabled by default, as seen in the docs here : https://www.keycloak.org/docs/latest/server_installation/#profiles

To enable it, you can either :

  • Create a file standalone/configuration/profile.properties with feature.scripts=enabled

or

  • start the server with bin/standalone.sh|bat -Dkeycloak.profile.feature.scripts=enabled

And it seems from the source code

public boolean isSupported() {
    return Profile.isFeatureEnabled(Profile.Feature.SCRIPTS) && Profile.isFeatureEnabled(Profile.Feature.UPLOAD_SCRIPTS);
}

that the upload_scripts should be enabled likewise

I hope it will help someone

ulk200
  • 369
  • 3
  • 5
  • 2
    Thanks for commenting, I figured it also then found your post :-). Doc says that we should not enable script upload in production but we should deploy scripts on the server : https://www.keycloak.org/docs/latest/server_development/#using-keycloak-administration-console-to-upload-scripts – Guenole de Cadoudal Jun 19 '20 at 07:19