Thanks :)


Sorry for the rather long mail - steps to demo are first, for some additional thoughts see below.


Is there any chance of having a 1.10.x release line?


if you want to try it out you could apply this patch against a new branch from current master:

https://github.com/thomasdarimont/keycloak/commit/3f39479e7fa0c75941cd524ba99de5c85db43b62.patch

then just start the org.keycloak.testsuite.KeycloakServer.


In the admin-console you need to do the following:

1) copy the browser authentication flow to "browser script"

2) in the "browser script forms" subflow click on Actions -> Add execution

3) select "Script based authentication" from the list

4) Mark "Script based authentication" as required

5) configure "Script based authentication" via actions -> config

6) as config parameters use

Alias: auth-tracer-script (this is later shown in the auth flow listing)

Script Engine: Nashorn

ScriptName: auth-tracer

Script:


function authenticate(context){

 

 LOG.info(scriptName + " --> trace auth for: " + user.username);


 context.success();

}


function action(context){

 context.attempted();

}


7) Save the authenticator

8) Goto bindings tab and set the browser flow to "browser script".

9) end.


I usually create a test user to play with this.


I'm keen to get this done since we need to be rather flexible regarding auth logic.

Btw. the Auth0 rules repository is a great example for what can be done with this feature:

https://github.com/auth0/rules


Some things to consider:


# Use cases

I think scripting should not only be applied for authenticators but also for other components like: event listeners, federation-providers, even custom user action scripts that are performed on login / logout / account / profile updates also configurable validation scripts would be helpful.

https://issues.jboss.org/browse/KEYCLOAK-1872?jql=project%20%3D%20KEYCLOAK%20AND%20text%20~%20%22forgerock%22


# Implementation

In my naive implementation I just externalized the authenticate(..) and action(..) method.

I think it might be easier for users to have dedicated scriptable authenticators (or rather authentication steps? since they only participate in the authentication but might not decide or authenticate anything...) e.g. ones that just perform some enrichment of the user model, additional tracing etc. others could be more complex by conditionally showing forms, using the providers to send codes (email, sms) etc.


In my POC I exposed a bunch of context variables to the script:

https://github.com/thomasdarimont/keycloak/commit/3f39479e7fa0c75941cd524ba99de5c85db43b62#diff-50db206e6dcd6842014f5be864e6c895R89

One should either be very selective here or just hand in securable wrappers that would allow to control access from scripts to context objects.


Allowing users to writing / editing scripts in the admin frontend is great but it would be more helpful if those scripts could be loaded from an external directory that would allow a proper versioning of the scripts outside of keycloak.


Having a ScriptingProvider capable of loading / saving scripts and executing scripts against a provided context would be useful. Within the scriptable components one would then just refer to a script from a “Script Repository”.


A script should have metadata like a script name, comment, script source, perhaps vcs information.


# Security

Offering scripting support of course opens the door to all kind of bad things - I don’t think that my initial assumption “scripts will probably only be specified by administrators and executed on the server…” will hold for long ;-)

Soner or later one probably needs some sort of sandbox concept here - the Auht0 guys do this:

“For security reasons, the Rules code runs in a JavaScript sandbox based on webtask.io where you can use the full power of the ECMAScript 5 language.


For a list of currently supported sandbox modules, see: Modules Supported by the Sandbox.”


# UX for Script Support


I think users needs both syntax highlighting and linenumbers for readable scripts both are provided by the currently used ace editor (https://ace.c9.io/#nav=about )- another popular option would have been codemirror (http://codemirror.net/) but personally I found it easier to integrate ace.


Within the admin console it should be possible to view a script in read-only mode - perhaps this should be the default when opening a component like an authenticator. editing should be enabled via a checkbox or on/off-switch.


The ace editor support could be used to render a highlighted (read-only) version of JSON (client install) and XML (SAML) configuration.


We need to find a way to parameterize the ace editor for various other "script" types to get proper highlighting (used in kc-provider-config.html -> mode: xxxx) - perhaps” code” would be a more generic type than "script".


It would really help to have some server-side validation being performed on save of an authenticator (or any other object), validation errors should be propagated to the frontend and shown near the "culprit".


# Documentation


The user guide should include a section about scripting support in general.

Some examples should show the usage of scripting support, e.g. an authenticator, an event listener.



Cheers,

Thomas