JBoss.org Community Documentation

- Prev
- Next

## Chapter 4. Providers and SPIs

Keycloak is designed to cover most use-cases without requiring custom code, but we also want it to be customizable. To achive this Keycloak has a number of SPIs which you can implement your own providers for.

## 4.1. Implementing a SPI

To implement an SPI you need to implement it's ProviderFactory and Provider interfaces. You also need to create a provider-configuration file. For example to implement the Event Listener SPI you need to implement EventListenerProviderFactory and EventListenerProvider and also provide the file `META-INF/services/org.keycloak.events.EventListenerProviderFactory`

For example to implement the Event Listener SPI you start by implementing EventListenerProviderFactory:

    {
    package org.acme.provider;

    import ...

    public class MyEventListenerProviderFactory implements EventListenerProviderFactory {

        private List<Event> events;

        public String getId() {
            return "my-event-listener";
        }

        public void init(Config.Scope config) {
            int max = config.getInt("max");
            events = new MaxList(max);
        }

        public EventListenerProvider create(KeycloakSession session) {
            return new MyEventListenerProvider(events);
        }

        public void close() {
            events = null;
        }

    }
    }

The example uses an imagined MaxList which has a maximum size and is concurrency safe. When the maximum size is reached and new entries are added the oldest entry is removed. Keycloak creates a single instance of EventListenerProviderFactory which makes it possible to store state for multiple requests. EventListenerProvider instances are created by calling create on the factory for each requests so these should be light-weight.

Next you would implement EventListenerProvider:

    {
    package org.acme.provider;

    import ...

    public class MyEventListenerProvider implements EventListenerProvider {

        private List<Event> events;

        public MyEventListenerProvider(List<Event> events) {
            this.events = events;
        }

        @Override
        public void onEvent(Event event) {
            events.add(event);
        }

        @Override
        public void close() {

        }

    }
    }

The file `META-INF/services/org.keycloak.events.EventListenerProviderFactory` should contain the full name of your ProviderFactory implementation:

    org.acme.provider.MyEventListenerProviderFactory

## 4.2. Registering provider implementations

Keycloak can load provider implementations from JBoss Modules or directly from the file-system. Using Modules is recommended as you can control exactly what classes are available to your provider. Any providers loaded from the file-system uses a classloader with the Keycloak classloader as its parent.

### 4.2.1. Register a provider using Modules

To register a provider using Modules first create a module. To do this you can either use the jboss-cli script or manually create a folder inside KEYCLOAK_HOME/modules and add your jar and a `module.xml`. For example to add the event listener sysout example provider using the jboss-cli script execute:

    {
        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-model-api,org.keycloak.keycloak-events-api"
    }

Or to manually create it start by creating the folder `KEYCLOAK_HOME/modules/org/keycloak/examples/event-sysout/main`. Then copy `event-listener-sysout-example.jar` to this folder and create `module.xml` with the following content:

    {
    <?xml version="1.0" encoding="UTF-8"?>
    <module xmlns="urn:jboss:module:1.1" name="org.keycloak.examples.event-sysout">
        <resources>
            <resource-root path="event-listener-sysout-example.jar"/>
        </resources>
        <dependencies>
            <module name="org.keycloak.keycloak-core"/>
            <module name="org.keycloak.keycloak-model-api"/>
            <module name="org.keycloak.keycloak-events-api"/>
        </dependencies>
    </module>
    }

Once you've created the module you need to register this module with Keycloak. This is done by editing keycloak-server.json and adding it to the providers:

    {
        "providers": [
            ...
            "module:org.keycloak.examples.event-sysout"
        ]
    }

### 4.2.2. Register a provider using file-system

To register your provider simply copy the JAR including the ProviderFactory and Provider classes and the provider configuration file to `standalone/configuration/providers`.

You can also define multiple provider class-path if you want to create isolated class-loaders. To do this edit keycloak-server.json and add more classpath entries to the providers array. For example:

    {
        "providers": [
            "classpath:provider1.jar;lib-v1.jar",
            "classpath:provider2.jar;lib-v2.jar"
        ]
    }

The above example will create two separate class-loaders for providers. The classpath entries follow the same syntax as Java classpath, with ';' separating multiple-entries. Wildcard is also supported allowing loading all jars (files with .jar or .JAR extension) in a folder, for example:

    {
        "providers": [
            "classpath:/home/user/providers/*"
        ]
    }

### 4.2.3. Configuring a provider

You can pass configuration options to your provider by setting them in `keycloak-server.json`. For example to set the max value for `my-event-listener` add:

    {
        "eventsListener": {
            "my-event-listener": {
                "max": 100
            }
        }
    }

## 4.3. Available SPIs

Here's a list of the available SPIs and a brief description. For more details on each SPI refer to individual sections.

Account
  Provides the account manage console pages. The default implementation uses FreeMarker templates.
Connections Infinispan
  Loads and configures Infinispan connections. The default implementation can load connections from the Infinispan subsystem, or alternatively can be manually configured in keycloak-server.json.
Connections Jpa
  Loads and configures Jpa connections. The default implementation can load datasources from WildFly/EAP, or alternatively can be manually configured in keycloak-server.json.
Connections Jpa Updater
  Updates database schema. The default implementation uses Liquibase.
Connections Mongo
  Loads and configures MongoDB connections. The default implementation is configured in keycloak-server.json.
Email
  Formats and sends email. The default implementation uses FreeMarker templates and JavaMail.
Events Listener
  Listen to user related events for example user login success and failures. Keycloak provides two implementations out of box. One that logs events to the server log and another that can send email notifications to users on certain events.
Events Store
  Store user related events so they can be viewed through the admin console and account management console. Keycloak provides implementations for Relational Databases and MongoDB.
Export
  Exports the Keycloak database. Keycloak provides implementations that export to JSON files either as a single file, multiple files in a directory or a encrypted ZIP archive.
Import
  Imports an exported Keycloak database. Keycloak provides implementations that import from JSON files either as a single file, multiple files in a directory or a encrypted ZIP archive.
Login
  Provides the login pages. The default implementation uses FreeMarker templates.
Login Protocol
  Provides protocols. Keycloak provides implementations of OpenID Connect and SAML 2.0.
Realm
  Provides realm and application meta-data. Keycloak provides implementations for Relational Databases and MongoDB.
Realm Cache
  Caches realm and application meta-data to improve performance. Keycloak provides a basic in-memory cache and a Infinispan cache.
Theme
  Allows creating themes to customize look and feel. Keycloak provides implementations that can load themes from the file-system or classpath.
Timer
  Executes scheduled tasks. Keycloak provides a basic implementation based on java.util.Timer.
User
  Provides users and role-mappings. Keycloak provides implementations for Relational Databases and MongoDB.
User Cache
  Caches users and role-mappings to improve performance. Keycloak provides a basic in-memory cache and a Infinispan cache.
User Federation
  Support syncing users from an external source. Keycloak provides implementations for LDAP and Active Directory.
User Sessions
  Provides users session information. Keycloak provides implementations for basic in-memory, Infinispan, Relational Databases and MongoDB

- PrevChapter 3. Installation and Configuration of Keyc...
- Top of page
- Front page
- NextChapter 5. Running Keycloak Server on OpenShift