4

I made a custom SPI for my keycloak server and now I have to configure it on the Admin console.

I added the SPI as a module, with manual installation, so I have it on modules/{package-name}/main, with the module.xml; I have also put the on standalone.xml, and the also in the keycloak-server subsystem.

After all this configuration, I then go to the admin console to configure the custom user provider and it does not appear in the list.

What can I do?

Jonas
  • 121,568
  • 97
  • 310
  • 388
ourobor93
  • 372
  • 1
  • 7
  • 21

3 Answers3

2

Found a way of doing this, it's to add files inside classpath:${jboss.home.dir}/providers/, as SPI inside modules found there are interpreted by Keycloak.

More info on this post.

Selast Lambou
  • 708
  • 12
  • 27
1

My finally solution was applying the example from

https://github.com/thomasdarimont/keycloak-user-storage-provider-demo

and changing the UserRepository for an EntityManager to connect with the database.

ourobor93
  • 372
  • 1
  • 7
  • 21
-1

Consider deploying you SPI implementation as JAR or EAR. I've also faced some trouble when i want to deploy them to keycloak as JBoss module, but i don't remember what exactly (In my company we heavily customized Keycloak with custom SPI implementations including Authenticators, UserStorageProvider, REST endpoints, OIDC mappers ...). Now we are deploying them as EAR package. Here is how you can perform EAR packaging with maven:

<name>Keycloak Extensions EAR</name>

<artifactId>cardpay-extensions</artifactId>
<packaging>ear</packaging>

<properties>
    ...
</properties>

<dependencies>

    <!-- Your jars with provider implementations, I'm use two jars (for unit testing simplicity) -->

    <dependency>
        <groupId>com.acme</groupId>
        <artifactId>extensions-core</artifactId>
        <version>${project.version}</version>
        <type>jar</type>
    </dependency>

    <dependency>
        <groupId>com.acme</groupId>
        <artifactId>extensions-providers</artifactId>
        <version>${project.version}</version>
        <type>ejb</type>
    </dependency>

</dependencies>

<build>
    <finalName>${project.artifactId}</finalName>
    <plugins>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ear-plugin</artifactId>
            <version>3.0.1</version>
            <configuration>
                <version>8</version>
                <defaultLibBundleDir>lib</defaultLibBundleDir>
                <outputFileNameMapping>@{artifactId}@.@{extension}@</outputFileNameMapping>
            </configuration>
        </plugin>

    </plugins>
</build>

Don't forget to add main/application/META-INF/jboss-deployment-structure.xml like:

<?xml version="1.0" ?>
<jboss-deployment-structure>

<!-- Core module -->
<module name="deployment.extensions.core">
    <resources>
        <resource-root path="lib/core.jar"/>
    </resources>
    <dependencies>
        <module name="com.oracle.ojdbc" export="true"/>
        <module name="org.jboss.logging" export="true"/>
        <module name="org.apache.commons.io" export="true"/>
        <module name="javax.ws.rs.api" export="true"/>
        <module name="org.keycloak.keycloak-common" export="true"/>
        <module name="org.keycloak.keycloak-core" export="true"/>
        <module name="org.keycloak.keycloak-server-spi" export="true"/>
        <module name="org.keycloak.keycloak-server-spi-private" export="true"/>
        <module name="org.keycloak.keycloak-services" export="true"/>
    </dependencies>
</module>

<!-- Define dependency on core module for all sub-deployments -->
<deployment>
    <dependencies>
        <module name="deployment.extensions.core" export="true"/>
    </dependencies>
</deployment>

<!-- Providers bundle -->
<sub-deployment name="providers.jar">
    <dependencies>
        <module name="javax.api"/>
    </dependencies>
</sub-deployment>

</jboss-deployment-structure>

Now you can use maven-wildfly-plugin for mvn wildfly:deploy or manually deploy ear via JBoss cli or deployment scanner (check out Wildfly artifact deployment documentation). You should see corresponding messages in Wildfly logs about extensions deployment (there would be ProviderFactory id's)

Concerning unavailability of SPI implementations when using modules, I guess that is happen because JBoss modules loaded too early, so Keycloak deployer subsystem doesn't see them.

solveMe
  • 1,866
  • 1
  • 18
  • 20
  • Okey, now it works with the hot deploy, but it still does not appear in the list. Do I have to change the also? Because now I have "master" – ourobor93 Oct 03 '19 at 07:01
  • You can search for provider-id of your SPI implementation in ServerInfo -> Providers (It is server wide info). If you found it, so everything is OK. Which type of SPI you've implemented? – solveMe Oct 04 '19 at 03:37
  • Finally I apply the example from https://github.com/thomasdarimont/keycloak-user-storage-provider-demo changinf the UserRepository to an EntityManger and it works – ourobor93 Oct 04 '19 at 07:07
  • 1
    Oh yea EntityManager, finally remenber why deploying SPI implementations as static JBoss modules wasn't worked for me. As far as i understand Wildfly has EJB hooks only for dynamic deployments (EAR, WAR, JAR), but static modules initiated too early, so EntityManagers would not be injected to SPI beans. – solveMe Oct 10 '19 at 11:15