Keycloak, Tutorial, Java, Custom Event Listener

Keycloak - Custom Event Listener

Tutorial about how to create and deploy a custom event listener for Keycloak.

Author Martin
Martin23rd November 2020 - Updated 17th October 2022

This tutorial shows how you can create your very specific event listener in Keycloak. Keycloak supports almost 100 different event types. The example we're building in this tutorial will email an admin on every new registration. In this way somebody of the company will be notified whenever a new user signs up. The repository of the example can be found here.

How to create the listener?

In order to implement a custom event listener you need to implement the org.keycloak.events.EventListenerProvider interface. The function onEvent will be called on every event that happens in Keycloak. In this example we catch the REGISTER event and notify an admin user about the new registration.

1@Override
2public void onEvent(Event event) {
3
4  if (EventType.REGISTER.equals(event.getType())) {
5    log.infof("## NEW %s EVENT", event.getType());
6    log.info("-----------------------------------------------------------");
7
8    RealmModel realm = this.model.getRealm(event.getRealmId());
9    UserModel newRegisteredUser = this.session.users().getUserById(realm, event.getUserId());
10
11    String emailPlainContent = "New user registration\n\n" +
12        "Email: " + newRegisteredUser.getEmail() + "\n" +
13        "Username: " + newRegisteredUser.getUsername() + "\n" +
14        "Client: " + event.getClientId();
15
16    String emailHtmlContent = "<h1>New user registration</h1>" +
17        "<ul>" +
18        "<li>Email: " + newRegisteredUser.getEmail() + "</li>" +
19        "<li>Username: " + newRegisteredUser.getUsername() + "</li>" +
20        "<li>Client: " + event.getClientId() + "</li>" +
21        "</ul>";
22
23    DefaultEmailSenderProvider senderProvider = new DefaultEmailSenderProvider(session);
24
25    try {
26        senderProvider.send(session.getContext().getRealm().getSmtpConfig(), "admin@example.com", "Keycloak - New Registration", emailPlainContent, emailHtmlContent);
27    } catch (EmailException e) {
28        log.error("Failed to send email", e);
29    }
30
31    log.info("-----------------------------------------------------------");
32  }
33}
34

In order to be able to register this custom event listener class in Keycloak you will need to implement org.keycloak.events.EventListenerProviderFactory interface and return the newly created class in the create method.

1public class CustomEventListenerProviderFactory implements EventListenerProviderFactory {
2    @Override
3    public EventListenerProvider create(KeycloakSession keycloakSession) {
4        return new CustomEventListenerProvider(keycloakSession);
5    }
6
7    @Override
8    public void init(Config.Scope scope) {
9
10    }
11
12    @Override
13    public void postInit(KeycloakSessionFactory keycloakSessionFactory) {
14
15    }
16
17    @Override
18    public void close() {
19
20    }
21
22    @Override
23    public String getId() {
24        return "custom-event-listener";
25    }
26}
27

The final step before we can package our listener is to create the following file src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory. This will make sure that Keycloak can discover the new Listener.

it.aboutbits.CustomEventListenerProviderFactory

You can find the file in the example repository here.

How to deploy the artifact?

Once you created the artifact you have to copy the jar into your keycloak installation (/opt/keycloak/providers/). If you are using docker to run your Keycloak instance you can do the following:

1version: "3.7"
2
3services:
4  keycloak:
5    image: quay.io/keycloak/keycloak:19.0.3
6    command: start-dev
7    environment:
8      KC_LOG_LEVEL: info
9      KC_DB: postgres
10      KC_DB_URL: jdbc:postgresql://postgres/keycloak
11      KC_DB_USERNAME: keycloak
12      KC_DB_PASSWORD: password
13      KEYCLOAK_ADMIN: admin
14      KEYCLOAK_ADMIN_PASSWORD: password
15    volumes:
16      - ./custom-event-listener/target/custom-event-listener.jar:/opt/keycloak/providers/custom-event-listener.jar
17    depends_on:
18      - postgres
19    ports:
20      - 8080:8080
21
22  postgres:
23    image: postgres:12
24    environment:
25      POSTGRES_DB: keycloak
26      POSTGRES_USER: keycloak
27      POSTGRES_PASSWORD: password
28    ports:
29      - 5432:5432
30
31  mailhog:
32    image: mailhog/mailhog
33    ports:
34      - 8025:8025
35

How to enable the listener?

You're almost done. The listener should now be available in the list of event listeners. All you have to do now is to select the listener from the dropdown of available event listeners and save.

Register the event listener

To see a running example checkout the repository and follow the instructions in the readme.

Did you like this post?
We are happy to hear your feedback.

Get in touch