User session limit

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