Include a third party library in custom authenticator

I am creating plugins (providers) for keycloak using the Service Provider Interface. I have been able to build a couple. Now I need to add the smallrye-graphql-client library to query a graphql server. However, the library is not found in the classpath when I deploy the pluging.

Questions

  1. Is it possible to still create a jar which includes the dependency library?
  2. If 1 is not possible, can it be done with a war?
  3. How can I add the library to the classpath. Preferably, that those are added together with the plugin instead of statically to Wildfly. I am using gradle. More details below.

Background Info

I succeeded to create a class and integration test for it. However, when I deploy the plugin to keycloak I get a the following error:

16:38:38,127 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-1) 
             Uncaught server error: java.util.ServiceConfigurationError: no 
             io.smallrye.graphql.client.typesafe.api.GraphQlClientBuilder in classpath

I have configured gradle to include the dependency that caused the problem and also add it to the classpath. I suspect that I should add an entry to the jboss-deployment-structure.xml but I don’t know what I should write there.

The gradle configuration

plugins {
    id 'war'
    id 'java-library'
    id 'maven-publish'
}
repositories {
    mavenLocal()
    mavenCentral()
    jcenter()
}
configurations {
    dependenciesToInclude
}
dependencies {
    dependenciesToInclude "io.smallrye:smallrye-graphql-client:1.0.20"


    providedCompile group: 'javax.enterprise', name: 'cdi-api', version: '2.0'
    providedCompile "org.keycloak:keycloak-server-spi:${keycloakVersion}"
    providedCompile "org.keycloak:keycloak-server-spi-private:${keycloakVersion}"
    providedCompile("org.keycloak:keycloak-services:${keycloakVersion}") {
        exclude group: 'org.slf4j', module: 'slf4j-api'
        exclude group: 'org.slf4j', module: 'slf4j-log4j12'
    }
    providedCompile group: 'org.keycloak', name: 'keycloak-model-api', version: '1.8.1.Final'
    providedCompile "org.jboss.resteasy:resteasy-jaxrs"

    providedCompile group: 'org.eclipse.microprofile.graphql', name: 'microprofile-graphql-api', version: '1.0.3'
    compile group: 'org.apache.geronimo.config', name: 'geronimo-config-impl', version: '1.2.2'
    configurations.compile.extendsFrom(configurations.dependenciesToInclude)
}


jar {
    manifest {
        attributes(
                "Class-Path": configurations.dependenciesToInclude.collect { it.getName() }.join(' '))
    }
    from {
        configurations.dependenciesToInclude.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

I unzip the jar file and this is how the manifest looks like

❯ cat META-INF/MANIFEST.MF                                                                                                                                                                                                     ─╯
Manifest-Version: 1.0
Class-Path: smallrye-graphql-client-1.0.20.jar geronimo-config-impl-1.2.
 2.jar smallrye-graphql-client-api-1.0.20.jar microprofile-graphql-api-1
 .0.3.jar microprofile-config-api-1.3.jar org.osgi.annotation.versioning
 -1.0.0.jar

Bellow is the jboss-deployment-structure.xml. There you can see my attempt to include the graphql library (commented out)

<jboss-deployment-structure>
    <deployment>
        <dependencies>
            <module name="org.keycloak.keycloak-services"/>
            <module name="org.keycloak.keycloak-saml-core-public"/>
            <module name="org.apache.commons.codec"/>
            <module name="org.apache.commons.lang"/>
            <module name="org.jboss.logging"/>
            <!--            <module name="io.smallrye.smallrye-graphql-client"/>-->
        </dependencies>
    </deployment>
</jboss-deployment-structure>

I am using Keycloak 11.0.2 (WildFly Core 12.0.3.Final)

Hi @alvaroarenashel,

from your post I am not sure if you have added the graphql-client library as a module.
If you did, then you should just add it as a module dependency as you did in your sample.
Otherwise you can just add it to your WAR.The WAR should contain only the graphql-client JARs while the Keycloak JARs should be referenced by the jboss-deployment-structure.xml.

Also, take a look at Keycloak Custom SPI Deployment with external Jar where a very similar question has been asked.

Hi,

You have two options: you can follow @martinleim advice, in this case you have add all your dependencies to keycloak in advance and create also a module.xml for each. Another solution would be to use an ear deployment with all your dependencies inside.

Here are some examples:

1 Like

Hi @zak,

thank you for taking the time to respond. Using the examples that you shared and the one below I got my extension packaged as ear and working.

Welcome, glad it works out!