Reputation: 1
We are working on one usecase where we want to restric creating role at client level if the same role name doesn’t existing on realm level.
We did try this with EventListenerProvider
and with that we were able to get those exceptions logged into terminal/logs but that was not restricting anything on UI instead it was creating role on client level. which means with EventListenerProvider we were just getting that into log only and there are no pop-ups/messages or even not stopping client to creat role.
Attaching the java files that i had in custom event lister. CustomEventListenerProvider.java
package com.example.keycloak;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.ForbiddenException;
import org.jboss.logging.Logger;
import org.keycloak.events.Event;
import org.keycloak.events.EventListenerProvider;
import org.keycloak.events.admin.AdminEvent;
import org.keycloak.events.admin.OperationType;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RoleModel;
import org.keycloak.events.admin.ResourceType;
import java.io.IOException;
public class CustomEventListenerProvider implements EventListenerProvider {
private final KeycloakSession session;
private final ObjectMapper objectMapper = new ObjectMapper();
public CustomEventListenerProvider(KeycloakSession session) {
this.session = session;
}
@Override
public void onEvent(Event event) {
}
@Override
public void onEvent(AdminEvent event, boolean includeRepresentation) {
if (event.getOperationType() == OperationType.CREATE &&
event.getResourceType() == ResourceType.CLIENT_ROLE) {
try {
JsonNode representation = objectMapper.readTree(event.getRepresentation());
String roleName = representation.get("name").asText();
RoleModel realmRole = session.roles().getRealmRole(session.getContext().getRealm(), roleName);
if (realmRole == null) {
throw new Exception("Client-level role creation is not allowed unless the same role exists at the realm level.");
}
} catch (Exception e) {
throw new ModelDuplicateException("Failed to parse event representation");
}
}
}
@Override
public void close() {
// Cleanup resources if needed
}
}
src/main/java/com/example/keycloak/CustomEventListenerProviderFactory.java
package com.example.keycloak;
import org.keycloak.Config;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.events.EventListenerProvider;
import org.keycloak.events.EventListenerProviderFactory;
public class CustomEventListenerProviderFactory implements EventListenerProviderFactory {
@Override
public EventListenerProvider create(KeycloakSession session) {
return new CustomEventListenerProvider(session);
}
@Override
public void init(Config.Scope config) {
// Initialization code if necessary
}
@Override
public void postInit(KeycloakSessionFactory factory) {
// Post initialization code if necessary
}
@Override
public void close() {
// Cleanup code if necessary
}
@Override
public String getId() {
return "custom-event-listener";
}
}
src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory
com.example.keycloak.CustomEventListenerProviderFactory
Then I created .jar, moved that jar into the provider folder, and built and ran keycloak.(As per this doc) Ps: After login, i have enabled that customer event lister under realm setting.
Upvotes: 0
Views: 43