Home > Blockchain >  How to retrieve the list of online and offline sessions attached to a user using Keycloak's SPI
How to retrieve the list of online and offline sessions attached to a user using Keycloak's SPI

Time:01-16

In the aim to implement a synchronous per user/per group max sessions limitation, I do manage to retrieve login events using EventListenerProvider keycloak SPI as described here But from the user I would need to retrieve the list of sessions, online and offline

The provided API seems to give access to that sessions and to allow deletion of it, as described in this example.

But in my case it returns no sessions at all, either in version 11.0.3, 19.0.1 or 20.01

@JBossLog
public class PhoenixEventListenerProvider implements EventListenerProvider {

    private final KeycloakSession keycloakSession;
    private final KeycloakContext keycloakContext;
    private final RealmProvider realmProvider;
    private final ClientProvider clientProvider;
    private final UserSessionProvider userSessionProvider;
    
    private static String clientRealm = "myRealm";
    public PhoenixEventListenerProvider(KeycloakSession keycloakSession) {
        this.keycloakSession = keycloakSession;
        this.keycloakContext = keycloakSession.getContext();
        this.realmProvider = keycloakSession.realms();
        this.clientProvider = keycloakSession.clients();
        this.userSessionProvider = keycloakSession.sessions();
    }

    /**
     * https://www.keycloak.org/docs-api/20.0.2/javadocs/org/keycloak/models/UserSessionProvider.html#getUserSession(org.keycloak.models.RealmModel,java.lang.String)
     *
     * @param event
     */
    @Override
    public void onEvent(Event event) {

      if (event.getType().name().toUpperCase().contains("LOGIN") && event.getRealmId().equals(clientRealm)) {

        RealmModel realmM = keycloakContext.getRealm();
        ClientModel clientM = keycloakContext.getClient();
        String userId = event.getUserId();

        long offlineSessionsCount = userSessionProvider.getOfflineSessionsCount(realmM,clientM);
        long nbActiveUserSessions = userSessionProvider.getActiveUserSessions(realmM,clientM);
        UserSessionModel userSessionModel = userSessionProvider.getUserSession(realmM,userId);
        UserSessionModel offlineUserSessionModel = userSessionProvider.getOfflineUserSession(realmM,userId);
        String result= MessageFormat.format(
            "nbActiveUserSessions: {0}\n"  
            "offlineSessionsCount: {1}\n"  
            "userSessionModel.getId(): {2}\n"  
            "offlineUserSessionModel.getId(): {3}\n",

            Long.toString(nbActiveUserSessions),
            Long.toString(offlineSessionsCount),
            userSessionModel.getId(),
            offlineUserSessionModel.getId()
        );
        log.info(result);
    }
  }
}`

after login of a user the event is received, but result is 0 for nbActiveUserSessions,offlineSessionsCount and returned ids ar null.

nbActiveUserSessions: 0
offlineSessionsCount: 0
userSessionModel: null
offlineUserSessionModel: null

Would you know how to retrieve the sessions , whithout using any asynchronous call like if using the REST API ?

CodePudding user response:

Apparently, the new session is created after the LOGIN event, so the list of session available are the already existing ones. If necessary, another SPI should probably be used to act on the session beeing created .

  • Related