To prevent multiple sessions, I use the “User session count limiter” step, as indicated in the documentation. My question is: is there a way to prevent this check from being skipped for a specific user? For example, the “admin” user? Thanks
You can’t skip the limit on a per-user basis.
Howerver, I believe it is automatically skipped for service account users, but I don’t think that satisfies your case.
So the only way is to create a provider extension? Is there no way to work with flows?
Do you know if there is any custom extension that already does this job? thx
Not that I know of. Probably not difficult to write. You’d need to store the limit value as a user attribute, and then use the UserSessionProvider to fetch how many sessions the user has open.
hey @MarcelloT you can do it by yourself with custom extension as you said.
The logic is based on User Event and you will create EventListener looking for LOGIN event.
your provider will extend implements EventListenerProvider {
and also you will have factory implements EventListenerProviderFactory.
public class SessionLimiterProviderFactory implements EventListenerProviderFactory {
public static final String PROVIDER_ID = “session-limit”;@Override public EventListenerProvider create(KeycloakSession session) { logger.debug("called create"); return new SessionEventListenerProvider(session); } @Override public String getId() { return PROVIDER_ID; }…. other methods empty
}
Then remove existing sessions on LOGIN event, but here you have user context and you can do your customization:
public class SessionLimiterProviderFactory implements EventListenerProvider {
private final KeycloakSession session;
public SessionEventListenerProvider(KeycloakSession session) {
this.session = session;
}
@Override
public void onEvent(Event event) {
if (event.getType().equals(EventType.LOGIN)) {
RealmModel realmModel = session.getContext().getRealm();
UserModel userModel = session.users().getUserById(realmModel, event.getUserId());
session.sessions().getUserSessionsStream(realmModel, userModel).forEach(userSession -> {
if (!userSession.getId().equals(event.getSessionId())) {
session.sessions().removeUserSession(realmModel, userSession);
}
});
}
}
.... rest methods empty
you have to define your provider in:
org.keycloak.events.EventListenerProviderFactory under META-INF.services