@POST @Path("/remove-expired") @Produces(MediaType.APPLICATION_JSON) public Response removeExpired(@QueryParam("realm") final String name) { RealmManager realmManager = new RealmManager(session); RealmModel realm = realmManager.getRealmByName(name); if (realm == null) { throw new NotFoundException("Realm not found"); } session.sessions().removeExpired(realm); return Response.ok().build(); }
@POST @Path("/remove-user-sessions") @Produces(MediaType.APPLICATION_JSON) public Response removeUserSessions(@QueryParam("realm") final String realmName) { RealmManager realmManager = new RealmManager(session); RealmModel realm = realmManager.getRealmByName(realmName); if (realm == null) { throw new NotFoundException("Realm not found"); } session.sessions().removeUserSessions(realm); return Response.ok().build(); }
@POST @Path("/remove-user-session") @Produces(MediaType.APPLICATION_JSON) public Response removeUserSession(@QueryParam("realm") final String name, @QueryParam("session") final String sessionId) { RealmManager realmManager = new RealmManager(session); RealmModel realm = realmManager.getRealmByName(name); if (realm == null) { throw new NotFoundException("Realm not found"); } UserSessionModel sessionModel = session.sessions().getUserSession(realm, sessionId); if (sessionModel == null) { throw new NotFoundException("Session not found"); } session.sessions().removeUserSession(realm, sessionModel); return Response.ok().build(); }
@GET @Path("/get-user-session") @Produces(MediaType.APPLICATION_JSON) public Integer getLastSessionRefresh(@QueryParam("realm") final String name, @QueryParam("session") final String sessionId) { RealmManager realmManager = new RealmManager(session); RealmModel realm = realmManager.getRealmByName(name); if (realm == null) { throw new NotFoundException("Realm not found"); } UserSessionModel sessionModel = session.sessions().getUserSession(realm, sessionId); if (sessionModel == null) { throw new NotFoundException("Session not found"); } return sessionModel.getLastSessionRefresh(); }
@Override public boolean loadSessions(KeycloakSession session, int first, int max) { if (log.isTraceEnabled()) { log.tracef("Loading sessions - first: %d, max: %d", first, max); } UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class); List<UserSessionModel> sessions = persister.loadUserSessions(first, max, true); for (UserSessionModel persistentSession : sessions) { // Save to memory/infinispan UserSessionModel offlineUserSession = session.sessions().importUserSession(persistentSession, true); for (ClientSessionModel persistentClientSession : persistentSession.getClientSessions()) { ClientSessionModel offlineClientSession = session.sessions().importClientSession(persistentClientSession, true); offlineClientSession.setUserSession(offlineUserSession); } } return true; }
for (String sessionId : action.getKeycloakSessionIds()) { String brokerSessionId = getConfig().getAlias() + "." + sessionId; UserSessionModel userSession = session.sessions().getUserSessionByBrokerSessionId(realm, brokerSessionId); if (userSession != null && userSession.getState() != UserSessionModel.State.LOGGING_OUT
@GET @Path("logout_response") public Response logoutResponse(@Context UriInfo uriInfo, @QueryParam("state") String state) { UserSessionModel userSession = session.sessions().getUserSession(realm, state); if (userSession == null) { logger.error("no valid user session"); EventBuilder event = new EventBuilder(realm, session, clientConnection); event.event(EventType.LOGOUT); event.error(Errors.USER_SESSION_NOT_FOUND); return ErrorPage.error(session, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR); } if (userSession.getState() != UserSessionModel.State.LOGGING_OUT) { logger.error("usersession in different state"); EventBuilder event = new EventBuilder(realm, session, clientConnection); event.event(EventType.LOGOUT); event.error(Errors.USER_SESSION_NOT_FOUND); return ErrorPage.error(session, Messages.SESSION_NOT_ACTIVE); } return AuthenticationManager.finishBrowserLogout(session, realm, userSession, uriInfo, clientConnection, headers); }
@Override public void eventReceived(ClusterEvent event) { Map<String, SessionData> lastSessionRefreshes = ((LastSessionRefreshEvent) event).getLastSessionRefreshes(); if (logger.isDebugEnabled()) { logger.debugf("Received refreshes. Offline %b, refreshes: %s", offline, lastSessionRefreshes); } lastSessionRefreshes.entrySet().stream().forEach((entry) -> { String sessionId = entry.getKey(); String realmId = entry.getValue().getRealmId(); int lastSessionRefresh = entry.getValue().getLastSessionRefresh(); // All nodes will receive the message. So ensure that each node updates just lastSessionRefreshes owned by him. if (shouldUpdateLocalCache(sessionId)) { KeycloakModelUtils.runJobInTransaction(sessionFactory, (kcSession) -> { RealmModel realm = kcSession.realms().getRealm(realmId); UserSessionModel userSession = offline ? kcSession.sessions().getOfflineUserSession(realm, sessionId) : kcSession.sessions().getUserSession(realm, sessionId); if (userSession == null) { logger.debugf("User session '%s' not available on node '%s' offline '%b'", sessionId, topologyInfo.getMyNodeName(), offline); } else { // Update just if lastSessionRefresh from event is bigger than ours if (lastSessionRefresh > userSession.getLastSessionRefresh()) { // Ensure that remoteCache won't be updated due to this kcSession.setAttribute(IGNORE_REMOTE_CACHE_UPDATE, true); userSession.setLastSessionRefresh(lastSessionRefresh); } } }); } }); }
@Override public OfflinePersistentWorkerResult loadSessions(KeycloakSession session, OfflinePersistentLoaderContext loaderContext, OfflinePersistentWorkerContext ctx) { int first = ctx.getWorkerId() * sessionsPerSegment; log.tracef("Loading sessions for segment: %d", ctx.getSegment()); UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class); List<UserSessionModel> sessions = persister.loadUserSessions(first, sessionsPerSegment, true, ctx.getLastCreatedOn(), ctx.getLastSessionId()); log.tracef("Sessions loaded from DB - segment: %d", ctx.getSegment()); UserSessionModel lastSession = null; if (!sessions.isEmpty()) { lastSession = sessions.get(sessions.size() - 1); // Save to memory/infinispan session.sessions().importUserSessions(sessions, true); } int lastCreatedOn = lastSession==null ? Time.currentTime() + 100000 : lastSession.getStarted(); String lastSessionId = lastSession==null ? FIRST_SESSION_ID : lastSession.getId(); log.tracef("Sessions imported to infinispan - segment: %d, lastCreatedOn: %d, lastSessionId: %s", ctx.getSegment(), lastCreatedOn, lastSessionId); return new OfflinePersistentWorkerResult(true, ctx.getSegment(), ctx.getWorkerId(), lastCreatedOn, lastSessionId); }