Javascript Authenticator Provider

After upgrading to 7.0.1 version I found that administrators cannot upload scripts to the server.
The problem is that I use the feature.scripts preview in a custom authenticator flow and when I run keycloak instance the Admin Console does not display my custom authenticator flow.

To reenable again the feature I need to add -Dkeycloak.profile.feature.upload_scripts=enabled but I don’t understand how the feature.scripts and feature.upload_scripts are related.
Will also the feature.scripts be removed in the future even if the documentation
profiles display it as a preview?

If I remove the option -Dkeycloak.profile.feature.upload_scripts=enabled and create the JAR package to upload my JS script as explained in javascript-providers
I don’t know how to link the js script inside of my custom authenticator flow inside Admin Console.

Someone can explain correctly how to add a script-based authenticator flow with the 7.0.1 version, pls?

I found that the JS script is supported effectively only if both feature.scripts and feature.upload_script are enabled as described clearly in this commit.
Obviously this means that in the future the feature.scripts will be deprecated also and the Script-based authenticator feature will be removed right?

Finally I found what I did wrong…

All JS scripts authenticators deployed with the JAR package are avaiable in the list of the provider field as the name specified in the META-INF/keycloak-scripts.json when adding a new execution.

I was searching the Script value in the list of the provider field.

This means that old script-based authenticator must be recreated with the Admin Console.

Also the feature.upload_scripts can be safely disabled.

1 Like

I am having a similar issue with 10.0.1.

  • Deploying my Javascript Provider (also verifying the deploy by a fail-test)

The problem is that my Javascript provider (should be the name in keycloak-scripts.json) does not show as an option in “execution” (Authentication Flows).

Any suggestions?

Hi, I didnt upgrade to 10.0.1 version, therefore I don’t know whether there are some changes in the feature. Are you sure that feature.scripts has been activated? Here the
doc

Hello,
That’s it, it works now. Thanks!

Hello, you could share your .jar file?
I’m also using 10.0.1 version with the same JAR package explained in javascript-providers
and my customized Authentication Flows does not show as an option anywhere.
I already sat Dkeycloak.profile.feature.upload_scripts=enabled and Dkeycloak.profile.feature.scripts=enabled both separate and together, but it didn’t work.
However, in the Keycloak log I can see that the jar was deployed and no error occurred:
14:32:30,658 INFO [org.jboss.as.server.deployment] (MSC service thread 1-1) WFLYSRV0027: Starting deployment of “test.jar” (runtime-name: “test.jar”)
14:32:37,627 INFO [org.jboss.as.server] (ServerService Thread Pool – 35) WFLYSRV0010: Deployed “test.jar” (runtime-name : “test.jar”)
Thank you in advance

I fixed it adding to startap
ExecStart=/opt/keycloak/current/bin/standalone.sh -b 127.0.0.1 -Dkeycloak.profile.feature.scripts=enabled

I am on keycloak-11.0.0 version and I start keycloak with

./bin/standalone.sh -Dkeycloak.profile.feature.upload_scripts=enabled -Dkeycloak.profile.feature.scripts=enabled

and I deployed my custom JS authenticator using instructions in javascript-providers

In the logs I see

[org.jboss.as.server] (ServerService Thread Pool -- 33) WFLYSRV0010: Deployed "myfile.jar" (runtime-name : "myfile.jar")

But i do not see my JS authenticator in the list of providers.
Hm…

Any help would be appreciated.

I gave my script a unique name, downgraded to keycloak-10.0.2 and I am now running it with command

./bin/standalone.sh -Dkeycloak.profile.feature.upload_scripts=enabled -Dkeycloak.profile.feature.scripts=enabled

I do see my script among the list of providers:

but when I do login and logout using my application, I do not see any output from the script. Not in stdout, not in stderr of the server.

I have my debug level set on DEBUG.

Do I need to somehow enable JavaScript authenticator providers for my application?
If so, how do i do this?

I met the same problem and found your posts. Thanks for this.

I also had different problem when I wanted to deploy several time the same script (that are different by the call they make to an http server) and it was not possible. The unique id of the script is the file name in the jar file rather than the name.

So the script itself needs to be be duplicated. I have automated the jar creation in a javascript module you can find in npmjs “keycloak-rest-authenticator”. The idea is to have a generic script that will forward the requests to an external http server endpoint and the http server response will act on the keycloak data model to continue the workflow.

Hope it help

Thanks for the response @guenoledc.

I have already figured out how to get script authenticator called upon user login and I’ve seen seen your code at GitLab

I have a question about this line of code - what are these “actions” that the script authenticator gets called with?

More specifically, I need my custom authenticator to be called when the user logs out. Where you able to do this with your authenticator? Does it take some special configuration on Keycloak side?

Thanks for your help.

Hi @constfilin-sgn,

Concerning the line of code that you are referring to where the “action” constant string is passed to handleCall as mode parameter. This parameter is simply marshalled as json in the createBody function that then calls the http node js service. In this service, this parameter is read in the RestAuthenticator handler here to test whether the handler has been called for the first time (authenticate) or after a form action or else as an interruption from a form.

Concerning the second point on triggering the custom authenticator at time of logout, my authenticator cannot do this and I feel that it should be possible by setting logout actions (see this keycloak code) but I have not investigated this.

What do you need to customize at time of logout? I find it dangerous to rely on calling the logout since there is no guarantee that the user will effectively perform a logout.

I have a setup like this:

MyApp <=OIDC=> Keycloak <=SAML2=> Source_of_Users  

and I am doing SSO (SingleSignOn) and SLO (SingleLogOut) between MyApp and Source_of_Users.

SLO is particularly important - when/if the user logs out from Source_of_Users, I want the user to be automatically logged out from MyApp. If user does not log out from Source_of_Users, I do not worry about this.

I have implemented the polling scenario where MyApp periodically polls KeyCloak to see if the user is still logged in but I want to avoid polling and get Keycloak proactively notify MyApp when/if users logs out from Source_of_Users. That’s why I am developing this JavaScript authenticator. Hope I am on the right track.

Thanks for the tip about client logout actions.

Hi @constfilin-sgn

I am not sure what you mean by

How does the user logs out ?
1- On an application different from MyApp that only interact with Source_of_Users IDP
2- On an application different from MyApp that interact with Keycloak in OIDC
3- On MyApp (I guess it is not the case)

In your polling scenario you seem to have been able to get keycloak been made aware of the disconnection on Source_of_Users IDP. How is this happening ? A backend call from Source_of_Users to Keycloak ? A browser redirection to keycloak ?

In a precedent experience, I have had a scenario where the best approach was to wrap a keycloak endpoint to perform some actions before and after keycloak actual endpoint. So I wrote a process that implement the logic and calls the keycloak endpoint like a reverse proxy would do and configured an actual reverse proxy (in front of both keycloak and my process) to redirect the keycloak url to my program. May such an approach could be used to catch the logout event sent from Source_of_Users to Keycloak

user does this on in a browser window with Source_of_Users (i.e. the real identity provider)

get keycloak been made aware of the disconnection on Source_of_Users IDP

when user logs out from Source_of_Users then Source_of_Users sends SAML2 logout request to KeyCloak and KeyCloak does a backchannel user logout (without informing the frontchannel, i.e. MyApp)

best approach was to wrap a keycloak endpoint to perform some actions before and after keycloak actual endpoint

Thanks for the tip. Basically, this would mean that I need to wrap KeyCloak SAML2 endpoint into my handler. Looks like I am out of other ideas.

Ok, I see.

I don’t know how to get Keycloak call a logout backchannel url in my app (I can dig but where …)

So yes I think your conclusion is the best approach so far