Java Code Examples for org.keycloak.models.UserSessionModel#getStarted()

The following examples show how to use org.keycloak.models.UserSessionModel#getStarted() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: OfflinePersistentUserSessionLoader.java    From keycloak with Apache License 2.0 6 votes vote down vote up
@Override
public OfflinePersistentWorkerResult loadSessions(KeycloakSession session, OfflinePersistentLoaderContext loaderContext, OfflinePersistentWorkerContext ctx) {
    int first = ctx.getWorkerId() * sessionsPerSegment;

    log.tracef("Loading sessions for segment=%d createdOn=%d lastSessionId=%s", ctx.getSegment(), ctx.getLastCreatedOn(), ctx.getLastSessionId());

    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 createdOn=%d lastSessionId=%s", ctx.getSegment(), ctx.getLastCreatedOn(), ctx.getLastSessionId());

    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);
}
 
Example 2
Source File: TokenManager.java    From keycloak with Apache License 2.0 6 votes vote down vote up
private boolean isUserValid(KeycloakSession session, RealmModel realm, AccessToken token, UserSessionModel userSession) {
    UserModel user = userSession.getUser();
    if (user == null) {
        return false;
    }
    if (!user.isEnabled()) {
        return false;
    }
    try {
        TokenVerifier.createWithoutSignature(token)
                .withChecks(NotBeforeCheck.forModel(session ,realm, user))
                .verify();
    } catch (VerificationException e) {
        return false;
    }

    if (token.getIssuedAt() + 1 < userSession.getStarted()) {
        return false;
    }
    return true;
}
 
Example 3
Source File: AuthenticationManager.java    From keycloak with Apache License 2.0 6 votes vote down vote up
public static boolean isSessionValid(RealmModel realm, UserSessionModel userSession) {
    if (userSession == null) {
        logger.debug("No user session");
        return false;
    }
    int currentTime = Time.currentTime();

    // Additional time window is added for the case when session was updated in different DC and the update to current DC was postponed
    int maxIdle = userSession.isRememberMe() && realm.getSsoSessionIdleTimeoutRememberMe() > 0 ?
        realm.getSsoSessionIdleTimeoutRememberMe() : realm.getSsoSessionIdleTimeout();
    int maxLifespan = userSession.isRememberMe() && realm.getSsoSessionMaxLifespanRememberMe() > 0 ?
            realm.getSsoSessionMaxLifespanRememberMe() : realm.getSsoSessionMaxLifespan();

    boolean sessionIdleOk = maxIdle > currentTime - userSession.getLastSessionRefresh() - SessionTimeoutHelper.IDLE_TIMEOUT_WINDOW_SECONDS;
    boolean sessionMaxOk = maxLifespan > currentTime - userSession.getStarted();
    return sessionIdleOk && sessionMaxOk;
}
 
Example 4
Source File: AuthenticationManager.java    From keycloak with Apache License 2.0 6 votes vote down vote up
public static boolean isOfflineSessionValid(RealmModel realm, UserSessionModel userSession) {
    if (userSession == null) {
        logger.debug("No offline user session");
        return false;
    }
    int currentTime = Time.currentTime();
    // Additional time window is added for the case when session was updated in different DC and the update to current DC was postponed
    int maxIdle = realm.getOfflineSessionIdleTimeout() + SessionTimeoutHelper.IDLE_TIMEOUT_WINDOW_SECONDS;

    // KEYCLOAK-7688 Offline Session Max for Offline Token
    if (realm.isOfflineSessionMaxLifespanEnabled()) {
        int max = userSession.getStarted() + realm.getOfflineSessionMaxLifespan();
        return userSession.getLastSessionRefresh() + maxIdle > currentTime && max > currentTime;
    } else {
        return userSession.getLastSessionRefresh() + maxIdle > currentTime;
    }
}
 
Example 5
Source File: UserSessionPersisterProviderTest.java    From keycloak with Apache License 2.0 5 votes vote down vote up
private List<UserSessionModel> loadPersistedSessionsPaginated(KeycloakSession session, boolean offline, int sessionsPerPage, int expectedPageCount, int expectedSessionsCount) {
    UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);

    int count = persister.getUserSessionsCount(offline);

    int pageCount = 0;
    boolean next = true;
    List<UserSessionModel> result = new ArrayList<>();
    int lastCreatedOn = 0;
    String lastSessionId = "abc";

    while (next) {
        List<UserSessionModel> sess = persister.loadUserSessions(0, sessionsPerPage, offline, lastCreatedOn, lastSessionId);

        if (sess.size() < sessionsPerPage) {
            next = false;

            // We had at least some session
            if (sess.size() > 0) {
                pageCount++;
            }
        } else {
            pageCount++;

            UserSessionModel lastSession = sess.get(sess.size() - 1);
            lastCreatedOn = lastSession.getStarted();
            lastSessionId = lastSession.getId();
        }

        result.addAll(sess);
    }

    Assert.assertEquals(expectedPageCount, pageCount);
    Assert.assertEquals(expectedSessionsCount, result.size());
    return result;
}
 
Example 6
Source File: CrossDCLastSessionRefreshChecker.java    From keycloak with Apache License 2.0 5 votes vote down vote up
public SessionUpdateTask.CrossDCMessageStatus shouldSaveClientSessionToRemoteCache(
        KeycloakSession kcSession, RealmModel realm, SessionEntityWrapper<AuthenticatedClientSessionEntity> sessionWrapper, UserSessionModel userSession, boolean offline, int newTimestamp) {

    SessionUpdateTask.CrossDCMessageStatus baseChecks = baseChecks(kcSession, realm ,offline);
    if (baseChecks != null) {
        return baseChecks;
    }

    UUID clientSessionId = sessionWrapper.getEntity().getId();

    if (offline) {
        Integer lsrr = sessionWrapper.getLocalMetadataNoteInt(AuthenticatedClientSessionEntity.LAST_TIMESTAMP_REMOTE);
        if (lsrr == null) {
            lsrr = userSession.getStarted();
        }

        if (lsrr + (realm.getOfflineSessionIdleTimeout() / 2) <= newTimestamp) {
                logger.debugf("We are going to write remotely for clientSession %s. Remote timestamp: %d, New timestamp: %d",
                        clientSessionId, lsrr, newTimestamp);
            return SessionUpdateTask.CrossDCMessageStatus.SYNC;
        }
    }

    if (logger.isDebugEnabled()) {
        logger.debugf("Skip writing timestamp to the remoteCache. ClientSession %s timestamp %d", clientSessionId, newTimestamp);
    }

    return SessionUpdateTask.CrossDCMessageStatus.NOT_NEEDED;
}
 
Example 7
Source File: TokenManager.java    From keycloak with Apache License 2.0 4 votes vote down vote up
public TokenValidation validateToken(KeycloakSession session, UriInfo uriInfo, ClientConnection connection, RealmModel realm,
                                     RefreshToken oldToken, HttpHeaders headers) throws OAuthErrorException {
    UserSessionModel userSession = null;
    boolean offline = TokenUtil.TOKEN_TYPE_OFFLINE.equals(oldToken.getType());

    if (offline) {

        UserSessionManager sessionManager = new UserSessionManager(session);
        userSession = sessionManager.findOfflineUserSession(realm, oldToken.getSessionState());
        if (userSession != null) {

            // Revoke timeouted offline userSession
            if (!AuthenticationManager.isOfflineSessionValid(realm, userSession)) {
                sessionManager.revokeOfflineUserSession(userSession);
                throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Offline session not active", "Offline session not active");
            }

        } else {
            throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Offline user session not found", "Offline user session not found");
        }
    } else {
        // Find userSession regularly for online tokens
        userSession = session.sessions().getUserSession(realm, oldToken.getSessionState());
        if (!AuthenticationManager.isSessionValid(realm, userSession)) {
            AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, connection, headers, true);
            throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Session not active", "Session not active");
        }
    }

    UserModel user = userSession.getUser();
    if (user == null) {
        throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Invalid refresh token", "Unknown user");
    }

    if (!user.isEnabled()) {
        throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "User disabled", "User disabled");
    }

    if (oldToken.getIssuedAt() + 1 < userSession.getStarted()) {
        logger.debug("Refresh toked issued before the user session started");
        throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Refresh toked issued before the user session started");
    }


    ClientModel client = session.getContext().getClient();
    AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId());

    // Can theoretically happen in cross-dc environment. Try to see if userSession with our client is available in remoteCache
    if (clientSession == null) {
        userSession = new UserSessionCrossDCManager(session).getUserSessionWithClient(realm, userSession.getId(), offline, client.getId());
        if (userSession != null) {
            clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId());
        } else {
            throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Session doesn't have required client", "Session doesn't have required client");
        }
    }

    if (!client.getClientId().equals(oldToken.getIssuedFor())) {
        throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Unmatching clients", "Unmatching clients");
    }

    try {
        TokenVerifier.createWithoutSignature(oldToken)
                .withChecks(NotBeforeCheck.forModel(client), NotBeforeCheck.forModel(session, realm, user))
                .verify();
    } catch (VerificationException e) {
        throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Stale token");
    }

    // Setup clientScopes from refresh token to the context
    String oldTokenScope = oldToken.getScope();

    // Case when offline token is migrated from previous version
    if (oldTokenScope == null && userSession.isOffline()) {
        logger.debugf("Migrating offline token of user '%s' for client '%s' of realm '%s'", user.getUsername(), client.getClientId(), realm.getName());
        MigrationUtils.migrateOldOfflineToken(session, realm, client, user);
        oldTokenScope = OAuth2Constants.OFFLINE_ACCESS;
    }

    ClientSessionContext clientSessionCtx = DefaultClientSessionContext.fromClientSessionAndScopeParameter(clientSession, oldTokenScope, session);

    // Check user didn't revoke granted consent
    if (!verifyConsentStillAvailable(session, user, client, clientSessionCtx.getClientScopes())) {
        throw new OAuthErrorException(OAuthErrorException.INVALID_SCOPE, "Client no longer has requested consent from user");
    }

    clientSessionCtx.setAttribute(OIDCLoginProtocol.NONCE_PARAM, oldToken.getNonce());

    // recreate token.
    AccessToken newToken = createClientAccessToken(session, realm, client, user, userSession, clientSessionCtx);

    return new TokenValidation(user, userSession, clientSessionCtx, newToken);
}
 
Example 8
Source File: UserInfoEndpoint.java    From keycloak with Apache License 2.0 4 votes vote down vote up
private void checkTokenIssuedAt(AccessToken token, UserSessionModel userSession, EventBuilder event) throws ErrorResponseException {
    if (token.getIssuedAt() + 1 < userSession.getStarted()) {
        event.error(Errors.INVALID_TOKEN);
        throw newUnauthorizedErrorResponseException(OAuthErrorException.INVALID_TOKEN, "Stale token");
    }
}
 
Example 9
Source File: LogoutEndpoint.java    From keycloak with Apache License 2.0 4 votes vote down vote up
private void checkTokenIssuedAt(IDToken token, UserSessionModel userSession) throws OAuthErrorException {
    if (token.getIssuedAt() + 1 < userSession.getStarted()) {
        throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Refresh toked issued before the user session started");
    }
}