'How to use keycloak-admin-client with custom Keycloak provider
I am building a docker image based on Keycloak 18 with my custom provider which uses Keycloak Admin REST Client. I figured that I need to bundle some dependencies as well so I created jar files with maven-dependency-plugin
and included those as well.
Here's my Dockerfile:
FROM maven:3.6.0-jdk-11-slim AS javabuild
ENV HOME=/home/app
RUN mkdir -p $HOME
WORKDIR $HOME
ADD pom.xml $HOME
ADD my-provider/pom.xml $HOME/my-provider/pom.xml
RUN mvn -pl my-provider verify --fail-never
ADD my-provider $HOME/my-provider
RUN rm -rf ${HOME}/my-provider/target
RUN mvn -pl my-provider install
RUN mvn -pl my-provider package
FROM quay.io/keycloak/keycloak:18.0.0 as builder
COPY --from=javabuild /home/app/my-provider/target/my-provider*.jar /opt/keycloak/providers/
COPY --from=javabuild /home/app/my-provider/target/dependency/*.jar /opt/keycloak/providers/
RUN /opt/keycloak/bin/kc.sh build
FROM quay.io/keycloak/keycloak:18.0.0
COPY --from=builder /opt/keycloak/ /opt/keycloak/
WORKDIR /opt/keycloak
ENTRYPOINT ["/opt/keycloak/bin/kc.sh", "start-dev", "--db=postgres"]
I have difficult time to understand what I should exactly provide and how.
I tried to use keycloak-admin-client
directly and only add that as dependency and no transient dependecies as it seems that Keycloak already has these dependencies available as since Keycloak 17 they use Quarkus. I don't know much about Quarkus but looking into docker container files I found:
bash-4.4$ ls | grep "rest"
com.openshift.openshift-restclient-java-8.0.0.Final.jar
io.quarkus.quarkus-resteasy-2.7.5.Final.jar
io.quarkus.quarkus-resteasy-common-2.7.5.Final.jar
io.quarkus.quarkus-resteasy-jackson-2.7.5.Final.jar
io.quarkus.quarkus-resteasy-server-common-2.7.5.Final.jar
org.jboss.resteasy.resteasy-core-4.7.5.Final.jar
org.jboss.resteasy.resteasy-core-spi-4.7.5.Final.jar
org.jboss.resteasy.resteasy-jackson2-provider-4.7.5.Final.jar
org.jboss.resteasy.resteasy-jaxb-provider-4.7.5.Final.jar
org.jboss.resteasy.resteasy-multipart-provider-4.7.5.Final.jar
If I run my provider the following in my provider:
public class MyProvider implements RealmResourceProvider {
private final Keycloak keycloak;
public MyProvider(KeycloakSession session) {
RealmModel realm = session.getContext().getRealm();
this.keycloak = KeycloakBuilder.builder()
.serverUrl("http://localhost:8080")
.realm(realm.getId())
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.clientId("admin-cli")
.clientSecret("...")
.build();
UserResource user = this.keycloak.realm(realm.getId()).users().get("admin");
System.out.println(user);
}
}
I will get
Uncaught server error: java.lang.ExceptionInInitializerError
Then I realized that maybe I should add org.jboss.resteasy.resteasy-client:4.7.5-Final
as well. Then I got
Uncaught server error: java.lang.NoClassDefFoundError: org/jboss/resteasy/client/jaxrs/ResteasyClientBuilder
Then I tried to add resteasy-client dependencies as well so after adding org.jboss.resteasy.resteasy-client-api:4.7.5-Final
I got
Uncaught server error: java.util.ServiceConfigurationError: org.jboss.resteasy.client.jaxrs.spi.ClientConfigProvider: org.wildfly.security.auth.client.spi.RESTEasyClientConfigProviderImpl Unable to get public no-arg constructor
...
Caused by: java.lang.NoClassDefFoundError: org/wildfly/client/config/ConfigXMLParseException
...
Caused by: java.lang.ClassNotFoundException: org.wildfly.client.config.ConfigXMLParseException
Then I realized that keycloack-admin-client
actually relies on resteasy-client
version 3.13.2.Final
and not 4.7.5-Final
. So I add these versions of resteasy-client
, resteasy-multipart-provider
, resteasy-jackson2-provider
and resteasy-jaxb-provider
and got
Uncaught server error: java.lang.InstantiationError: org.jboss.resteasy.spi.ResteasyProviderFactory
And now I have no idea what to try next.
I found this issue report which talks about Resteasy version conflict between Keycloak Admin REST Client and Quarkus and it mentions there's another package called quarkus-keycloack-admin-client
. So I added that as dependency and again I got:
Uncaught server error: java.lang.NoClassDefFoundError: org/keycloak/admin/client/KeycloakBuilder
also quarkus-keycloack-admin-client
is dependend on Keycloak 17 so I am not sure if it's 100% compatible with 18.
So my question is how I should include keycloack-admin-client
in my provider?
Solution 1:[1]
My Problems are very similar and I will try to build a customized quarkus-keycloak-server (https://blog.codecentric.de/2022/05/keycloak-x-aber-sicher-ohne-bekannte-sicherheitsluecken/) extended with dependencies needed by my own extensions. I dont know, if this will lead to a running system, but I'll hope so.
Solution 2:[2]
I had the same problem as you and I created a Keycloak ticket here: https://github.com/keycloak/keycloak/issues/11973
I solved this problem by myself by adding this:
I overrode the
resteasy-client
with version 4.7.5.Final.<!--Keycloak--> <dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-admin-client</artifactId> <scope>provided</scope> <exclusions> <exclusion> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-client</artifactId> </exclusion> <exclusion> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-multipart-provider</artifactId> </exclusion> <exclusion> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jackson2-provider</artifactId> </exclusion> <exclusion> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jaxb-provider</artifactId> </exclusion> </exclusions> </dependency> <!--Resteasy--> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-client</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-multipart-provider</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jackson2-provider</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jaxb-provider</artifactId> <scope>provided</scope> </dependency>
Because I got errors looks like:
Uncaught server error: java.util.ServiceConfigurationError: org.jboss.resteasy.client.jaxrs.spi.ClientConfigProvider: org.wildfly.security.auth.client.spi.RESTEasyClientConfigProviderImpl Unable to get public no-arg constructor
Caused by: java.lang.ClassNotFoundException: org.wildfly.client.config.ConfigXMLParseException
I found the dependency for this class and add this, it works for me :)
<dependency> <groupId>org.wildfly.client</groupId> <artifactId>wildfly-client-config</artifactId> <version>1.0.1.Final</version> </dependency>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | thsppi |
Solution 2 | LĂȘ H?ng Quy?n |