Hello there.
I’m trying to do this. I’ve just implemented an event listener where I remove all user sessions after the UPDATE_PASSWORD event. I am closing all sessions but I can’t find a way to redirect to login (browser flow) with a message.
My implementation is below:
UpdatePasswordEventListener.java
package cloud.poc.keycloak.authentication;
import org.keycloak.common.util.Time;
import org.keycloak.events.Event;
import org.keycloak.events.EventListenerProvider;
import org.keycloak.events.EventType;
import org.keycloak.events.admin.AdminEvent;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.FormMessage;
import org.keycloak.services.messages.Messages;
import org.keycloak.models.KeycloakContext;
import org.keycloak.models.RealmModel;
import org.keycloak.storage.adapter.InMemoryUserAdapter;
public class UpdatePasswordEventListener implements EventListenerProvider {
private final KeycloakSession keycloakSession;
public UpdatePasswordEventListener(KeycloakSession keycloakSession) {
this.keycloakSession = keycloakSession;
}
@Override
public void onEvent(Event event) {
if(!event.getType().equals(EventType.UPDATE_PASSWORD)) {
return;
}
RealmModel realm = keycloakSession.getContext().getRealm();
InMemoryUserAdapter user = new InMemoryUserAdapter(keycloakSession, realm, event.getUserId());
keycloakSession.sessions().getUserSessionsStream(realm, user).forEach(userSession -> {
// remove all existing user sessions
keycloakSession.sessions().removeUserSession(realm, userSession);
});
// Here I need to do something like bellow but I can't access to AuthenticationFlowContext
// context.forkWithSuccessMessage(new FormMessage(Messages.PASSWORD_UPDATED));
}
@Override
public void onEvent(AdminEvent event, boolean includeRepresentation) {
}
@Override
public void close() {
}
}
UpdatePasswordEventListenerFactory.java
package cloud.poc.keycloak.authentication;
import org.keycloak.Config;
import org.keycloak.events.EventListenerProvider;
import org.keycloak.events.EventListenerProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
public class UpdatePasswordEventListenerFactory implements EventListenerProviderFactory {
public static final String PROVIDER_ID = "update-password-event-listener";
@Override
public EventListenerProvider create(KeycloakSession keycloakSession) {
return new UpdatePasswordEventListener(keycloakSession);
}
@Override
public void init(Config.Scope config) {
}
@Override
public void postInit(KeycloakSessionFactory factory) {
}
@Override
public void close() {
}
@Override
public String getId() {
return PROVIDER_ID;
}
}
Could someone help me? Or let me know if there is a better solution for this requirement.
I’m working with KeyCloak V. 22.0.5
Regards, Fabricio.