Parsing the custom registration file fails when using the p1 auth plugin in keycloak 22
The snakeyaml library is old in the current build of snakeyaml. The p1 auth plugin must be built with JDK 17 to make it work with Keycloak v22. This will break the yaml parsing using snakeyaml library. The following stacktrace will ensue:
2023-10-13 20:34:02,149 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (executor-thread-7) Uncaught server error: java.lang.NoSuchMethodError: 'void org.yaml.snakeyaml.constructor.Constructor.<init>(java.lang.Class)'
at dod.p1.keycloak.utils.NewObjectProvider.getYaml(NewObjectProvider.java:45)
at dod.p1.keycloak.common.CommonConfig.loadConfigFile(CommonConfig.java:89)
at dod.p1.keycloak.common.CommonConfig.<init>(CommonConfig.java:50)
at dod.p1.keycloak.common.CommonConfig.getInstance(CommonConfig.java:75)
at dod.p1.keycloak.registration.X509Tools.getX509IdentityFromCertChain(X509Tools.java:188)
at dod.p1.keycloak.registration.X509Tools.getX509Identity(X509Tools.java:235)
at dod.p1.keycloak.registration.X509Tools.getX509Username(X509Tools.java:100)
at dod.p1.keycloak.registration.X509Tools.getX509Username(X509Tools.java:113)
at dod.p1.keycloak.registration.RegistrationValidation.buildPage(RegistrationValidation.java:177)
at org.keycloak.authentication.FormAuthenticationFlow.renderForm(FormAuthenticationFlow.java:304)
at org.keycloak.authentication.FormAuthenticationFlow.processFlow(FormAuthenticationFlow.java:285)
at org.keycloak.authentication.DefaultAuthenticationFlow.processSingleFlowExecutionModel(DefaultAuthenticationFlow.java:380)
at org.keycloak.authentication.DefaultAuthenticationFlow.processFlow(DefaultAuthenticationFlow.java:249)
at org.keycloak.authentication.AuthenticationProcessor.authenticateOnly(AuthenticationProcessor.java:1026)
at org.keycloak.authentication.AuthenticationProcessor.authenticate(AuthenticationProcessor.java:888)
at org.keycloak.protocol.oidc.endpoints.AuthorizationEndpoint.buildRegister(AuthorizationEndpoint.java:368)
at org.keycloak.protocol.oidc.endpoints.AuthorizationEndpoint.process(AuthorizationEndpoint.java:222)
at org.keycloak.protocol.oidc.endpoints.AuthorizationEndpoint.processInRetriableTransaction(AuthorizationEndpoint.java:147)
at org.keycloak.protocol.oidc.endpoints.AuthorizationEndpoint.buildGet(AuthorizationEndpoint.java:119)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:154)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:118)
at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:560)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:452)
at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:413)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:321)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:415)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:378)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:174)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:142)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:168)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:131)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:33)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:429)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:240)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:154)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:321)
at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:157)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:229)
at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:82)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:147)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:84)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:44)
at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
at io.vertx.ext.web.impl.RoutingContextWrapper.next(RoutingContextWrapper.java:200)
at io.quarkus.vertx.http.runtime.options.HttpServerCommonHandlers$1.handle(HttpServerCommonHandlers.java:58)
at io.quarkus.vertx.http.runtime.options.HttpServerCommonHandlers$1.handle(HttpServerCommonHandlers.java:36)
at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
at io.vertx.ext.web.impl.RoutingContextWrapper.next(RoutingContextWrapper.java:200)
at org.keycloak.quarkus.runtime.integration.web.QuarkusRequestFilter.lambda$createBlockingHandler$0(QuarkusRequestFilter.java:82)
at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:576)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:833)
The fix is to peg SnakeYaml to version 2.2 in build.gradle and modify the constructor method like so:
diff --git a/p1-keycloak-plugin/src/main/java/dod/p1/keycloak/utils/NewObjectProvider.java b/p1-keycloak-plugin/src/main/java/dod/p1/keycloak/utils/NewObjectProvider.java
index 4c5f0c9..70d8901 100644
--- a/p1-keycloak-plugin/src/main/java/dod/p1/keycloak/utils/NewObjectProvider.java
+++ b/p1-keycloak-plugin/src/main/java/dod/p1/keycloak/utils/NewObjectProvider.java
@@ -3,6 +3,7 @@ package dod.p1.keycloak.utils;
import dod.p1.keycloak.common.YAMLConfig;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
+import org.yaml.snakeyaml.LoaderOptions;
import java.io.File;
import java.io.FileInputStream;
@@ -42,7 +43,7 @@ public final class NewObjectProvider {
* @return Yaml
*/
public static Yaml getYaml() {
- return new Yaml(new Constructor(YAMLConfig.class));
+ return new Yaml(new Constructor(YAMLConfig.class, new LoaderOptions()));
}
}
Changes to build.gradle
diff --git a/p1-keycloak-plugin/build.gradle b/p1-keycloak-plugin/build.gradle
index dccacb9..050c084 100644
--- a/p1-keycloak-plugin/build.gradle
+++ b/p1-keycloak-plugin/build.gradle
@@ -39,6 +39,7 @@ dependencies {
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.70'
implementation 'org.jboss.logmanager:log4j2-jboss-logmanager:1.1.1.Final'
+ implementation 'org.yaml:snakeyaml:2.2'
}
jar {
Edited by Kiran Thyagaraja