Skip to content

9945 java17 nashorn#11322

Merged
mposolda merged 3 commits intokeycloak:mainfrom
mposolda:9945-java17-nashorn
May 27, 2022
Merged

9945 java17 nashorn#11322
mposolda merged 3 commits intokeycloak:mainfrom
mposolda:9945-java17-nashorn

Conversation

@mposolda
Copy link
Copy Markdown
Contributor

No description provided.

@mposolda
Copy link
Copy Markdown
Contributor Author

mposolda commented Apr 14, 2022

@stianst @pedroigor @douglaspalmer

This is first draft of having script providers working on Java 17. Works for both KC on Wildfly and Quarkus.

How

The nashorn script engine, which was available automatically in Java earlier than 15, is not available anymore with the Java 15 or newer. (Will need to doublecheck the exact version before writing the docs).

Nashorn can be still used in Java 17, but just when it is explicitly added to classpath.

The idea we discussed is, that users will need to attach script engine themselves, so that we don't need to do productization of nashorn (or other script engine). So that's the approach I use in this draft.

Wildfly

On Wildfly, people will need to add jboss module "org.openjdk.nashorn.nashorn-core" with the nashorn-core-5.3.jar and the corresponding module.xml file.

There is an alternative to add different script engine provider (EG. graal js) by adding different module. Script module is configurable with the SPI with something like this:

            <spi name="scripting">
                <provider name="default" enabled="true">
                    <properties>
                        <property name="script-engine-module" value="org.openjdk.nashorn.nashorn-coree"/>
                    </properties>
                </provider>
            </spi>

Quarkus

On Quarkus, people will need to add 3 JAR files to the {kc.home}/providers directory:

  • nashorn-core.jar
  • asm.jar
  • asm-commons.jar
  • asm-util.jar

The last 2 are dependencies of nashorn (In Wildfly, asm is available automatically, so it is just sufficient to have it declared as dependency in nashorn module.xml).

I guess I can make it somehow more user-friendly on Quarkus, so guys does not need to copy 3 jars, but rather something like 1.

WDYT?

@mposolda mposolda requested a review from douglaspalmer April 14, 2022 15:01
Comment thread common/src/main/java/org/keycloak/common/util/Environment.java Outdated
@mposolda
Copy link
Copy Markdown
Contributor Author

mposolda commented Apr 22, 2022

@stianst @DGuhr @pedroigor I've sent draft PR to the quickstarts with some additional utilities and instructions on how to have script providers running on Keycloak server Wildfly and Quarkus keycloak/keycloak-quickstarts#316 . This PR is aligned with that quickstart PR.

Please let me know if you agree with the approach. I can then continue with the testsuite, documentation and polishing of the quickstart PR.

pedroigor
pedroigor previously approved these changes Apr 25, 2022
Copy link
Copy Markdown
Contributor

@pedroigor pedroigor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mposolda Looking forward to have these changes in :)

@mposolda
Copy link
Copy Markdown
Contributor Author

@pedroigor @DGuhr Thanks guys! Will move forward with the testsuite update for this PR and then will "undraft" it and ask you for re-review. So there will be some additional changes, but possibly just in the testsuite part.

@mposolda mposolda force-pushed the 9945-java17-nashorn branch from 372a0b0 to 2e8af58 Compare May 18, 2022 16:58
@mposolda mposolda marked this pull request as ready for review May 18, 2022 16:59
@mposolda
Copy link
Copy Markdown
Contributor Author

@pedroigor @DGuhr @kami619 I've removed the "draft" flag from this PR and I've updated testsuite part. Now the script tests should be working on JDK 17 on both Wildfly and Quarkus. Do you please have a chance to re-review this PR?

I've added testsuite changes in the latest commit for the easier re-review, but I am planning to squash the commits before merge. I am also planning to follow with the PRs for the quickstarts and documentation.

@kami619 In order to have tests passing on JDK 17, there is also need to prepare the servers with JDK 17 to have the necessary nashorn bits available on the servers. I've used this for my testing on local machine with Java 17:

cd testsuite/integration-arquillian/servers
mvn clean install -Pauth-server-wildfly
cd ../tests/base
mvn clean install -Pauth-server-wildfly -Dtest=ScriptAuthenticatorTest

Same should work also for auth-server-quarkus . And also it should hopefully work for all the other tests, which use javascript engine (protocol mappers, authorization), however I did not test other besides ScriptAuthenticatorTest.

@kami619
Copy link
Copy Markdown
Contributor

kami619 commented May 25, 2022

@mposolda thank you for the detailed instructions, I shall pick this up and test it on my local.

@mposolda
Copy link
Copy Markdown
Contributor Author

@pedroigor Thanks Pedro!

@kami619 Ok, Thanks. I will wait for you to confirm if your tests are ok before merging this.

@mabartos
Copy link
Copy Markdown
Contributor

mabartos commented May 26, 2022

@mposolda After some discussion with @kami619, I was trying to execute the ScriptAuthenticatorTest test with JDK11 and JDK17 on WF. For JDK11 everything works as expected, but for JDK17 there are some issues. It seems the Script authenticator doesn't work for me. I'll try to investigate it a little bit.

EDIT: I'll try to rebuild the whole project again. -> Still not working

Log:

12:25:30,115 WARN  [org.keycloak.services] (default task-1) KC-SERVICES0013: Failed authentication: java.lang.IllegalStateException: Could not find ScriptEngine for script: Script{id='null', realmId='test', name='scripts/auth-example.js', type='text/javascript', code='AuthenticationFlowError = Java.type("org.keycloak.authentication.AuthenticationFlowError");

function authenticate(context) {
    LOG.info(script.name + " --> trace auth for: " + user.username);
    if (user.username === "fail") {
        context.failure(AuthenticationFlowError.INVALID_USER);
        return;
    }
    context.success();
}', description='null'}
        at org.keycloak.keycloak-services@999-SNAPSHOT//org.keycloak.scripting.DefaultScriptingProvider.getPreparedScriptEngine(DefaultScriptingProvider.java:109)
        at org.keycloak.keycloak-services@999-SNAPSHOT//org.keycloak.scripting.DefaultScriptingProvider.prepareEvaluatableScript(DefaultScriptingProvider.java:69)
        at org.keycloak.keycloak-services@999-SNAPSHOT//org.keycloak.scripting.DefaultScriptingProvider.prepareInvocableScript(DefaultScriptingProvider.java:50)
        at org.keycloak.keycloak-services@999-SNAPSHOT//org.keycloak.authentication.authenticators.browser.ScriptBasedAuthenticator.getInvocableScriptAdapter(ScriptBasedAuthenticator.java:164)
        at org.keycloak.keycloak-services@999-SNAPSHOT//org.keycloak.authentication.authenticators.browser.ScriptBasedAuthenticator.tryInvoke(ScriptBasedAuthenticator.java:120)
        at org.keycloak.keycloak-services@999-SNAPSHOT//org.keycloak.authentication.authenticators.browser.ScriptBasedAuthenticator.authenticate(ScriptBasedAuthenticator.java:103)
        at org.keycloak.keycloak-services@999-SNAPSHOT//org.keycloak.authentication.DefaultAuthenticationFlow.processSingleFlowExecutionModel(DefaultAuthenticationFlow.java:460)
        at org.keycloak.keycloak-services@999-SNAPSHOT//org.keycloak.authentication.DefaultAuthenticationFlow.processFlow(DefaultAuthenticationFlow.java:264)

For JDK11, the script engine is created.
image

For JDK17 and Quarkus auth server, the engine is created as well. So, it's only related to WF.

INFO  [org.keycloak.services] (executor-thread-0) KC-SERVICES0106: Created script engine 'OpenJDK Nashorn', version '15.3' for the mime type 'text/javascript'

@mposolda
Copy link
Copy Markdown
Contributor Author

@mabartos Hmm.... This is strange.

I've just checked again in this branch. I've rebuild it with Java 11 (from the top codebase directory):

mvn clean install -DskipTests=true -Pdistribution

And then executed this with Java 17:

cd testsuite/integration-arquillian/servers
mvn clean install -Pauth-server-wildfly
cd ../tests/base
mvn clean install -Pauth-server-wildfly -Dtest=ScriptAuthenticatorTest

Last command works fine also with -Dtest=org.keycloak.testsuite.authz.AuthorizationTest (The test which @kami619 pointed to me this morning).

Do you see different results with the command sequence like this? If not, can you check if in the ZIP file testsuite/integration-arquillian/servers/auth-server/jboss/wildfly/integration-arquillian-servers-auth-server-wildfly-999-SNAPSHOT.zip you see the nashorn module inside auth-server-wildfly/modules/system/layers/keycloak/org/openjdk/nashorn/nashorn-core/main ?

Copy link
Copy Markdown
Contributor

@mabartos mabartos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mposolda Oh, sorry, I tried to repeat those steps again and it seems everything's fine even for the WF. Sorry for the confusion. The module is present there.

Manually tested with Open JDK11 and Open JDK17 and everything works as expected.

@kami619
Copy link
Copy Markdown
Contributor

kami619 commented May 27, 2022

@mabartos thanks for the confirmation. @mposolda lets merge it if its all good from your end as martin was able to verify it for us

@mposolda
Copy link
Copy Markdown
Contributor Author

@mabartos @kami619 Thanks guys!

@mposolda mposolda merged commit eed9442 into keycloak:main May 27, 2022
@BenjaminVettori
Copy link
Copy Markdown

BenjaminVettori commented Aug 30, 2022

For those looking for the jar files, here are the corresponding maven links:

I am uncertain if all dependencies of nashorn-core.jar are necessary, but when i looked them up at maven repository, i found those:

<dependencies>
    <dependency>
      <groupId>org.ow2.asm</groupId>
      <artifactId>asm</artifactId>
      <version>7.3.1</version>
    </dependency>
    <dependency>
      <groupId>org.ow2.asm</groupId>
      <artifactId>asm-commons</artifactId>
      <version>7.3.1</version>
    </dependency>
    <dependency>
      <groupId>org.ow2.asm</groupId>
      <artifactId>asm-tree</artifactId>
      <version>7.3.1</version>
    </dependency>
    <dependency>
      <groupId>org.ow2.asm</groupId>
      <artifactId>asm-util</artifactId>
      <version>7.3.1</version>
    </dependency>
  </dependencies>

seems like asm-tree was not mentioned before.
I added nashorn-core.jar (15.4) and the four dependency jar files (7.3.1) and then the default javascript policy started to work.

Just a small side-note: A Default (javascript) policy is generated, when you enable fine grained permissions for a client, even if the javascript dependency is missing. If you try to evaluate permissions with the default policy, there happens just nothing in the gui (no error, just a 500 response from the server in the developer tools). You have to look up server logs to find the root cause.

However, once you add the missing jar files to the provider folder and run kc.sh build, everything seems to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Script providers not working on OpenJDK 17 due to Nashorn being deprecated

6 participants