keycloak-aplcache

Details

diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractOIDCProtocolMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractOIDCProtocolMapper.java
index d267f91..a7eeb5d 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractOIDCProtocolMapper.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractOIDCProtocolMapper.java
@@ -67,7 +67,7 @@ public abstract class AbstractOIDCProtocolMapper implements ProtocolMapper {
             return token;
         }
 
-        setClaim(token, mappingModel, userSession);
+        setClaim(token, mappingModel, userSession, session);
         return token;
     }
 
@@ -78,7 +78,7 @@ public abstract class AbstractOIDCProtocolMapper implements ProtocolMapper {
             return token;
         }
 
-        setClaim(token, mappingModel, userSession);
+        setClaim(token, mappingModel, userSession, session);
         return token;
     }
 
@@ -89,7 +89,7 @@ public abstract class AbstractOIDCProtocolMapper implements ProtocolMapper {
             return token;
         }
 
-        setClaim(token, mappingModel, userSession);
+        setClaim(token, mappingModel, userSession, session);
         return token;
     }
 
@@ -98,7 +98,22 @@ public abstract class AbstractOIDCProtocolMapper implements ProtocolMapper {
      * @param token
      * @param mappingModel
      * @param userSession
+     *
+     * @deprecated override {@link #setClaim(IDToken, ProtocolMapperModel, UserSessionModel, KeycloakSession)} instead.
      */
+    @Deprecated
     protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession) {
     }
+
+    /**
+     * Intended to be overridden in {@link ProtocolMapper} implementations to add claims to an token.
+     * @param token
+     * @param mappingModel
+     * @param userSession
+     * @param keycloakSession
+     */
+    protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession, KeycloakSession keycloakSession) {
+        // we delegate to the old #setClaim(...) method for backwards compatibility
+        setClaim(token, mappingModel, userSession);
+    }
 }
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/ScriptBasedOIDCProtocolMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/ScriptBasedOIDCProtocolMapper.java
index 8b5025f..2dd6be0 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/ScriptBasedOIDCProtocolMapper.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/ScriptBasedOIDCProtocolMapper.java
@@ -18,17 +18,19 @@
 package org.keycloak.protocol.oidc.mappers;
 
 import org.jboss.logging.Logger;
+import org.keycloak.common.Profile;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
+import org.keycloak.models.ScriptModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
 import org.keycloak.provider.ProviderConfigProperty;
 import org.keycloak.provider.ProviderConfigurationBuilder;
 import org.keycloak.representations.IDToken;
+import org.keycloak.scripting.EvaluatableScriptAdapter;
+import org.keycloak.scripting.ScriptingProvider;
 
-import javax.script.Bindings;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
 import java.util.List;
 
 /**
@@ -59,7 +61,8 @@ public class ScriptBasedOIDCProtocolMapper extends AbstractOIDCProtocolMapper im
           " 'user' - the current user.\n" + //
           " 'realm' - the current realm.\n" + //
           " 'token' - the current token.\n" + //
-          " 'userSession' - the current userSession.\n" //
+          " 'userSession' - the current userSession.\n" + //
+          " 'keycloakSession' - the current keycloakSession.\n" //
       )
       .defaultValue("/**\n" + //
         " * Available variables: \n" + //
@@ -67,6 +70,7 @@ public class ScriptBasedOIDCProtocolMapper extends AbstractOIDCProtocolMapper im
         " * realm - the current realm\n" + //
         " * token - the current token\n" + //
         " * userSession - the current userSession\n" + //
+        " * keycloakSession - the current userSession\n" + //
         " */\n\n\n//insert your code here..." //
       )
       .add()
@@ -96,27 +100,33 @@ public class ScriptBasedOIDCProtocolMapper extends AbstractOIDCProtocolMapper im
 
   @Override
   public String getHelpText() {
-    return "Evaluates a javascript function to produce a token claim based on context information.";
+    return "Evaluates a JavaScript function to produce a token claim based on context information.";
   }
 
-  protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession) {
+  public boolean isSupported() {
+    return Profile.isFeatureEnabled(Profile.Feature.SCRIPTS);
+  }
+
+  protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession, KeycloakSession keycloakSession) {
 
     UserModel user = userSession.getUser();
-    String script = mappingModel.getConfig().get(SCRIPT);
+    String scriptSource = mappingModel.getConfig().get(SCRIPT);
     RealmModel realm = userSession.getRealm();
 
-    ScriptEngineManager engineManager = new ScriptEngineManager();
-    ScriptEngine scriptEngine = engineManager.getEngineByName("javascript");
+    ScriptingProvider scripting = keycloakSession.getProvider(ScriptingProvider.class);
+    ScriptModel scriptModel = scripting.createScript(realm.getId(), ScriptModel.TEXT_JAVASCRIPT, "token-mapper-script_" + mappingModel.getName(), scriptSource, null);
 
-    Bindings bindings = scriptEngine.createBindings();
-    bindings.put("user", user);
-    bindings.put("realm", realm);
-    bindings.put("token", token);
-    bindings.put("userSession", userSession);
+    EvaluatableScriptAdapter script = scripting.prepareEvaluatableScript(scriptModel);
 
     Object claimValue;
     try {
-      claimValue = scriptEngine.eval(script, bindings);
+      claimValue = script.eval((bindings) -> {
+        bindings.put("user", user);
+        bindings.put("realm", realm);
+        bindings.put("token", token);
+        bindings.put("userSession", userSession);
+        bindings.put("keycloakSession", keycloakSession);
+      });
     } catch (Exception ex) {
       LOGGER.error("Error during execution of ProtocolMapper script", ex);
       claimValue = null;