Keycloak has a number of SPIs where you can provide your own providers to hook in custom behavior. The custom providers can be deployed by copying the JAR into the providers
directory or it can be deployed as a module which provides greater control of the classpath for the provider.
Keycloak also has the ability to create themes to customize login pages and account management console. These can either be copied to the themes
directory or they can also be deployed as modules.
In this post I'll show how you can load custom providers and themes from a Maven repository. This could either be from the local Maven repository or a remove Maven repository.
Loading providers and themes from a Maven repository can be useful for development and also as a distribution mechanism, especially when Keycloak is clustered and you want to make sure all nodes have the same providers and themes.
Before going through these examples make sure you have the Keycloak server installed. If you don't you can get it from keycloak.org. We'll refer to the directory where you have the Keycloak server as KEYCLOAK_HOME
.
You also need to download the Keycloak examples as we'll use one of the example providers. You can get them from keycloak.org. Then extract the archive somewhere. We'll refer to the directory with the examples as EXAMPLES_HOME
.
Deploying Provider as a Module
Before we load the example provider from Maven we'll first deploy it as a module. There's two reasons for this. Firstly, we'll make sure that we have everything configured correctly and that the provider is working as expected. Secondly, loading the provider from Maven is actually a feature of the JBoss Modules which is what provides the support for modules in the first place.
To deploy the provider go through the following steps: Stop the Keycloak server, then build and install the example provider with the following steps:
cd $EXAMPLES_HOME/providers/event-listener-sysout mvn clean install $KEYCLOAK_HOME/bin/jboss-cli.sh --command="module add \ --name=org.keycloak.examples.event-sysout \ --resources=target/event-listener-sysout-example.jar \ --dependencies=org.keycloak.keycloak-core,org.keycloak.keycloak-server-spi"This will create a module for the example provider. Next we need to configure Keycloak to load providers from the. Open
$KEYCLOAK_HOME/standalone/configuration/keycloak-server.json
in a text editor and update the providers section to:
"providers": [ "classpath:${jboss.home.dir}/providers/*", "module:org.keycloak.examples.event-sysout" ],
Once you've done that start the Keycloak server and login to the Keycloak Admin Console. Select Events
from the menu, then click on the Config
tab. Remove the jboss-logging
listener, add sysout
and click on Save
. The sysout
event listener is the custom event listener provider we just deployed as a module.
To check that the provider is working as expected logout, then login again. You should see some events on the standard output from the Keycloak server:
Loading Provider from the Local Maven Repository
Loading the provider from the local Maven Repository is very easy. In the previous steps we already built and installed the provider into the local Maven Repository so we just need to make the module use the Maven artifact instead of the JAR directly from the module.
First stop the Keycloak server. Then delete the file modules/org/keycloak/examples/event-sysout/main/event-listener-sysout-example.jar
.
Next open $KEYCLOAK_HOME/modules/org/keycloak/examples/event-sysout/main/module.xml
in a text editor and change it to:
<?xml version="1.0" ?> <module xmlns="urn:jboss:module:1.1" name="org.keycloak.examples.event-sysout"> <resources> <artifact name="org.keycloak:event-listener-sysout-example:2.0.0.Final"/> </resources> <dependencies> <module name="org.keycloak.keycloak-core"/> <module name="org.keycloak.keycloak-server-spi"/> </dependencies> </module>
Note: if you are not using version 2.0.0.Final of the examples remember to change the version.
You can now start the server again and try login. You'll hopefully see that the events are still being printed to standard out. As you deleted the JAR from the module directory the provider is now being loaded from the local Maven repository.
Loading Provider from a Remote Maven Repository
Let's start by creating a Nexus repository we can use to deploy the provider to. We'll use Docker and the official Sonatype Nexus image. You can obviously use any Maven Repository you want, but for the sake of completeness we'll include steps to setup the repository as well. Make sure you have Docker installed then run:
docker run -d -p 8081:8081 sonatype/nexus
After a while you'll have a Sonatype Nexus Maven Repository running at http://localhost:8081. You can login to this with username admin
and password admin123
. Now let's deploy the example provider to this repository.
First edit the file .m2/settings.xml
in your home directory and add the credentials for the Sonatype Nexus repository:
<settings> ... <servers> <server> <id>local-nexus</id> <username>admin</username> <password>admin123</password> </server> </servers> </settings>Then edit
$EXAMPLES_HOME/providers/event-listener-sysout/pom.xml
. Add a distributionManagement element:
<distributionManagement> <repository> <id>local-nexus</id> <name>Local Nexus</name> <url>http://localhost:8081/content/repositories/releases</url> </repository> </distributionManagement>Also, you need to enable the deploy plugin as it's been disabled in the parent POM:
<build> <finalName>event-listener-sysout-example</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-deploy-plugin</artifactId> <configuration> <skip>false</skip> </configuration> </plugin> </plugins> </build>
Now you can run the following to deploy the provider to the repository:
mvn deploy
Check that it was indeed deployed by opening http://localhost:8081/content/repositories/releases/org/keycloak/event-listener-sysout-example/.
Stop Keycloak. To make sure the provider can indeed be retrieved from the remote Maven repository delete the directory .m2/repository/org/keycloak/event-listener-sysout-example
. This will remove the provider from the local Maven repository. You can try to start the Keycloak server again, but you will get a warning. To enable the remote Maven repository start the Keycloak server with:
bin/standalone.sh \ -Dremote.maven.repo=http://localhost:8081/content/repositories/releases
Keycloak should now start successfully and should download the provider from the remote Maven repository. It'll get cached in the local Maven repository so it won't have to retrieve it every time Keycloak is started.