Keycloak 12 - Script auth, require not defined

Hi,

I am currently testing keycloak. As part of the requirement i need to use another server in the authentication flow. In order to use that another server, I have to use a script.

First i enabled the script feature as it was not showing under execution options. Then I added my javascript to that.

However during authenticaiton, the server is complaining about require not defined. I have ensured the npm install require is done and the required module is present. But somehow keycloak is not able to see it. Is there any java class i need to include at the beginning of the script?

aused by: javax.script.ScriptException: ReferenceError: “require” is not defined in at line number 5
at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScrip
at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:4
at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine$3.eval(NashornScriptEngine.java:521
at java.scripting/javax.script.CompiledScript.eval(CompiledScript.java:89)
at org.keycloak.keycloak-services@12.0.3//org.keycloak.scripting.CompiledEvaluatableScriptAdapter.eval(Com
at org.keycloak.keycloak-services@12.0.3//org.keycloak.scripting.AbstractEvaluatableScriptAdapter.evalUnch

You are trying to use require() nodejs function in the javascript code. But Javascript API doesn’t have that function.

Thanks for looking into my question.
I did installed “require” with npm. So I want to know if this can be used at all with the nashorn engine that keycloak uses.

No, you can’t use nodejs, only js.

Google reminded me of an old blog post from myself: Frequently asked questions about Nashorn and Node.js | Niko Köbler – Software-Architect, Developer & Trainer

All mentioned options are totally expired and abandoned and shouldn’t be used any more.
As @jangaraj already mentioned, there is no possibility to use this on Nashorn.
Additionally, don’t rely on Nashorn, only because it’s here atm. Nashorn is deprecated and removed from latest Java versions!

1 Like

Thanks. So if we have to use script based authenticator in keycloak then what is the direction? is there a way to tell keycloak not to use nashorn then?

Write your script in plain JavaScript, w/o depending on other 3rd party libs which rely on require().

¯\_(ツ)_/¯

But even if I put a plain javascript, then i get the following message in the servers log. So i was thinking that no matter what is the content of the script, keycloak will always execute it with nashorn.

ERROR [stderr] (default task-190) Warning: Nashorn engine is planned to be removed from a future JDK release

Yes, Keycloak will run any JavaScript with Nashorn.
Yes, Nashorn is deprecated and marked for removal.
No, nobody knows how this will be handled by Keycloak in future.
Perhaps this option will be removed completely.
Perhaps Nashorn will be added as an add-on (see also Alternative to Nashorn engine for Scripts? - #3 by dasniko)
Perhaps something completely different.
:man_shrugging:

Thanks for the info. This will help me in my evaluation of Keycloak as IAM.

I was finally able to make it work in the way i wanted and scripts are running fine. The only open item for me at the moment is the usage of ActiveXObject in the script because i have a single legacy app that still works with IE11 and needs ActiveXObject. So even though its a dead tech and not recommended security wise, we have to support it for one customer untill they upgrade their application.

One confirmation i need from your expertise is that. The script that we add in the auth flow, how can i ensure that its executed in the browser and not at the keycloak server. What i mean is when the authentication happens, if i run the dev tool on the browser, i dont see the JS file executing , so i think it executes only on the server and not on the client browser. Is that so?

You are missing the point of script mapper feature. That script is running on the server side only (so no problem with ActiveX, IE11, …). It’s not script to manipulate with UI in the browser (it’s not like a jquery, angular, react, vue and other visual JS frameworks). It just extends functionality on the server side, e.g. add some additional claim to the token from the legacy API, …

1.) You can develop full Java code for your mapper functionality (“a lot” of work, packaging, deployment, …)

OR

2.) You can write the same functionality as Javascript code (faster, easier development, but probably you don’t have so many dev features as Java offers)
*it was mentioned that javascripting is deprecated feature, so it’s possible that only Java coding option will be supported in the future

If you need to run script in the browser (but I don’t see any business reason for that - except fancy UI), then modify templates. Only then you have to deal that UI can be running on different browsers.

Thanks for taking time to answer my queries and helping me out, But unfortunately running script on server side gives me ActiveXObject not defined error when the following lines of the script is executed in the authentication flow

var ax = new ActiveXObject(‘WScript.Network’);
var wksid = ax.computerName;

Since you mentioned running on the server side should not be a problem, then can you tell me how can I achieve running ActiveX?
I was thinking that the above lines of the code in a JS only makes sense when the JS loads in IE11 during authentication. If its loaded elsewhere then “ActiveXObject not defined” is an expected error.

Logical reasoning for the question: Can I use ActiveX in Keycloak Javascript code? (A few minutes of googling and you can have answer on your own)

Keycloak uses Nashorn JS engine. Which languages Nashorn support? Nashorn (JavaScript engine) - Wikipedia

It provides a 100% support of ECMAScript 5.1.[

Is ActiveX supported in ECMAScript 5.1? ECMAScript Language Specification - ECMA-262 Edition 5.1

No match found for ‘ActiveX’ in ECMAScript 5.1 doc → it’s not supported.

Q: Can I use ActiveX in Keycloak Javascript code?
A: No, because ActiveX is not supported in Nashorn, which is used Javascript engine in the Keycloak

Hello @myr

I just discovered your post and I have faced the same issue recently and posted an article and a solution on that problem.

It enables you to delegate authentication to an external nodejs solution you can fully control.

If you need help on this I can further explain.

Thanks Jangaraj, its clear to me now

Perfect, this is how the other application is where i need to make a HTTP POST calls to the REST endpoints and based on the response at Keycloak level show success or error.

I am going to try this out now. Will you have time to respond to my questions that i will have when i do it?

Also in this example you are running node.js express in a docker container in the same VM as Keycloak or Keycloak is separate VM and node.js express is separate?

Hi @myr

In the documentation I show effectively a keycloak running in a docker reaching the nodejs express service on my PC. I used my local environment do show exemple of the config.

For production, keycloak and the nodejs process cohabit on the same VM purely as a matter of simplicity, but it also have the benefit of reducing the latency when the authentication is called.

I can help you with some support (mostly in the evening - European time).

Thank you. I am in evaluation phase, so i have time till end of April to report if keycloak is the right tool for us. I have a VM at present for Keycloak and i will then put node.js in the same VM as well.