Custom EventListenerProvider - Get Created user in Admin Event

I’ve implemented a EventListenerProvider to capture when users are created in my keycloak instance. I am using the public void onEvent(AdminEvent event, boolean includeRepresentation), but I am having issues getting the created user so I can send a welcome email. How should I go about this?

  @Override
  public void onEvent(AdminEvent event, boolean includeRepresentation) {
    if (event.getResourceType() != ResourceType.USER || event.getOperationType() != OperationType.CREATE) {
      return;
    }

    // ex: users/544d5da6-b682-4143-8234-86212cc1dbc4
    String userId = event.getResourcePath().split("/")[1];
    LOG.debugf("UserCreationEventListenerProvider - UserId: [%s]", userId);

    RealmModel realm = session.realms().getRealm(event.getRealmId());
    LOG.debugf("UserCreationEventListenerProvider - Realm: [%s]", realm.getName());
    
    //UserModel user = session.users().getUserById(userId, realm);              //java.lang.NoSuchMethodError: 'org.keycloak.models.UserModel org.keycloak.models.UserProvider.getUserById(java.lang.String, org.keycloak.models.RealmModel)'
    //UserModel user = session.userStorageManager().getUserById(userId, realm); //java.lang.IllegalStateException: Access to the legacy store is no longer possible via this method. Adjust your code according to the Keycloak 19 Upgrading Guide.
    UserModel user = //???
    
    LOG.debugf("UserCreationEventListenerProvider - User: [%s]", user.getFirstName());

    SendEmail(realm, user);
  }

Seems that you compile your code with a (very) old version of the dependency and run it with a newer Keycloak server version. The method getUserById(userId, realm) is legacy, outdated and no more part of the most recent API. The actual method takes the arguments vice versa:

UserModel user = session.users().getUserById(realm, userId);

This should work.
Please test and return some feedback.

P.S.: Always use the same version of the dependencies in your extensions like your server will run!

1 Like

Thanks @dasniko. How can I check to see what version of the dependencies I’m currently using? I’m not super familiar with Java, sorry!

Is it in the pom.xml file?

<modelVersion>4.0.0</modelVersion>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <aws.version>2.15.1</aws.version>
        <junit.version>5.7.0</junit.version>
        <keycloak.version>12.0.1</keycloak.version>
        <maven-shade.version>3.2.4</maven-shade.version>
        <maven-surefire.version>2.22.2</maven-surefire.version>
        <mockito.version>2.25.1</mockito.version>
    </properties>

Edit: Server is running Version 20.0.3

Yes, pom.xml is your friend.
Most probably you are using the dependencies as of version 12.0.1, which is… very, very old… :wink:

1 Like

Also, if it makes it easier for you, I have a base class that helps with this here GitHub - p2-inc/keycloak-events: Useful Keycloak event listener implementations and utilities.

It allows you to implement a simple handler to create your listener for new users. For example:

public class MyUserAddRemove extends UserEventListenerProviderFactory {

  @Override
  public String getId() {
    return "ext-event-myuseraddremove";
  }

  @Override
  UserChangedHandler getUserChangedHandler() {
    return new UserChangedHandler() {
      @Override
      void onUserAdded(KeycloakSession session, RealmModel realm, UserModel user) {
        log.infof("User %s added to Realm %s", user.getUsername(), realm.getName());
      }

      @Override
      void onUserRemoved(KeycloakSession session, RealmModel realm, UserModel user) {
        log.infof("User %s removed from Realm %s", user.getUsername(), realm.getName());
      }
    };
  }
}

I updated the package version and my code, and I got past this issue. Thanks @dasniko !!!

Now I’ll go figure out why my custom template won’t load :slight_smile:

1 Like