Search in sources :

Example 16 with AuthenticatedClientSessionModel

use of org.keycloak.models.AuthenticatedClientSessionModel in project keycloak by keycloak.

the class UserSessionProviderTest method testRemoveUserSessionsByExpiredRememberMe.

/**
 * Tests the removal of expired sessions with remember-me enabled. It differs from the non remember me scenario by
 * taking into consideration the specific remember-me timeout values.
 *
 * @param session the {@code KeycloakSession}
 */
@Test
@ModelTest
public void testRemoveUserSessionsByExpiredRememberMe(KeycloakSession session) {
    RealmModel testRealm = session.realms().getRealmByName("test");
    int previousMaxLifespan = testRealm.getSsoSessionMaxLifespanRememberMe();
    int previousMaxIdle = testRealm.getSsoSessionIdleTimeoutRememberMe();
    try {
        ClientModel client = testRealm.getClientByClientId("test-app");
        Set<String> validUserSessions = new HashSet<>();
        Set<String> validClientSessions = new HashSet<>();
        Set<String> expiredUserSessions = new HashSet<>();
        // first lets update the realm by setting remember-me timeout values, which will be 4 times higher than the default timeout values.
        KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession kcSession) -> {
            RealmModel r = kcSession.realms().getRealmByName("test");
            r.setSsoSessionMaxLifespanRememberMe(r.getSsoSessionMaxLifespan() * 4);
            r.setSsoSessionIdleTimeoutRememberMe(r.getSsoSessionIdleTimeout() * 4);
        });
        // update the realm reference so that the remember-me timeouts are now visible.
        RealmModel realm = session.realms().getRealmByName("test");
        // create an user session with remember-me enabled that is older than the default 'max lifespan' timeout but not older than the 'max lifespan remember-me' timeout.
        // the session's last refresh also exceeds the default 'session idle' timeout but doesn't exceed the 'session idle remember-me' timeout.
        KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession kcSession) -> {
            Time.setOffset(-(realm.getSsoSessionMaxLifespan() * 2));
            UserSessionModel userSession = kcSession.sessions().createUserSession(realm, kcSession.users().getUserByUsername(realm, "user1"), "user1", "127.0.0.1", "form", true, null, null);
            AuthenticatedClientSessionModel clientSession = kcSession.sessions().createClientSession(realm, client, userSession);
            assertEquals(userSession, clientSession.getUserSession());
            Time.setOffset(-(realm.getSsoSessionIdleTimeout() * 2));
            userSession.setLastSessionRefresh(Time.currentTime());
            clientSession.setTimestamp(Time.currentTime());
            validUserSessions.add(userSession.getId());
            validClientSessions.add(clientSession.getId());
        });
        // create an user session with remember-me enabled that is older than the 'max lifespan remember-me' timeout.
        KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession kcSession) -> {
            Time.setOffset(-(realm.getSsoSessionMaxLifespanRememberMe() + 1));
            UserSessionModel userSession = kcSession.sessions().createUserSession(realm, kcSession.users().getUserByUsername(realm, "user1"), "user1", "127.0.0.1", "form", true, null, null);
            expiredUserSessions.add(userSession.getId());
        });
        // finally create an user session with remember-me enabled whose last refresh exceeds the 'session idle remember-me' timeout.
        KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession kcSession) -> {
            Time.setOffset(-(realm.getSsoSessionIdleTimeoutRememberMe() + SessionTimeoutHelper.PERIODIC_CLEANER_IDLE_TIMEOUT_WINDOW_SECONDS + 1));
            UserSessionModel userSession = kcSession.sessions().createUserSession(realm, kcSession.users().getUserByUsername(realm, "user2"), "user2", "127.0.0.1", "form", true, null, null);
            // no need to explicitly set the last refresh time - it is the same as the creation time.
            expiredUserSessions.add(userSession.getId());
        });
        // remove the expired sessions - the first session should not be removed as it doesn't exceed any of the remember-me timeout values.
        Time.setOffset(0);
        KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession kcSession) -> kcSession.sessions().removeExpired(realm));
        for (String sessionId : expiredUserSessions) {
            assertNull(session.sessions().getUserSession(realm, sessionId));
        }
        for (String sessionId : validUserSessions) {
            UserSessionModel userSessionLoaded = session.sessions().getUserSession(realm, sessionId);
            assertNotNull(userSessionLoaded);
            // the only valid user session should also have a valid client session that hasn't expired.
            AuthenticatedClientSessionModel clientSessionModel = userSessionLoaded.getAuthenticatedClientSessions().get(client.getId());
            assertNotNull(clientSessionModel);
            assertTrue(validClientSessions.contains(clientSessionModel.getId()));
        }
    } finally {
        Time.setOffset(0);
        session.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
        // restore the original remember-me timeout values in the realm.
        KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession kcSession) -> {
            RealmModel r = kcSession.realms().getRealmByName("test");
            r.setSsoSessionMaxLifespanRememberMe(previousMaxLifespan);
            r.setSsoSessionIdleTimeoutRememberMe(previousMaxIdle);
        });
    }
}
Also used : RealmModel(org.keycloak.models.RealmModel) ClientModel(org.keycloak.models.ClientModel) UserSessionModel(org.keycloak.models.UserSessionModel) ResetTimeOffsetEvent(org.keycloak.models.utils.ResetTimeOffsetEvent) KeycloakSession(org.keycloak.models.KeycloakSession) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) HashSet(java.util.HashSet) ModelTest(org.keycloak.testsuite.arquillian.annotation.ModelTest) ModelTest(org.keycloak.testsuite.arquillian.annotation.ModelTest) Test(org.junit.Test) AbstractTestRealmKeycloakTest(org.keycloak.testsuite.AbstractTestRealmKeycloakTest)

Example 17 with AuthenticatedClientSessionModel

use of org.keycloak.models.AuthenticatedClientSessionModel in project keycloak by keycloak.

the class UserSessionProviderTest method createClientSession.

private static AuthenticatedClientSessionModel createClientSession(KeycloakSession session, ClientModel client, UserSessionModel userSession, String redirect, String state) {
    RealmModel realm = session.realms().getRealmByName("test");
    AuthenticatedClientSessionModel clientSession = session.sessions().createClientSession(realm, client, userSession);
    clientSession.setRedirectUri(redirect);
    if (state != null)
        clientSession.setNote(OIDCLoginProtocol.STATE_PARAM, state);
    return clientSession;
}
Also used : RealmModel(org.keycloak.models.RealmModel) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel)

Example 18 with AuthenticatedClientSessionModel

use of org.keycloak.models.AuthenticatedClientSessionModel in project keycloak by keycloak.

the class UserSessionProviderTest method testCreateAndGetInSameTransaction.

@Test
@ModelTest
public void testCreateAndGetInSameTransaction(KeycloakSession session) {
    RealmModel realm = session.realms().getRealmByName("test");
    ClientModel client = realm.getClientByClientId("test-app");
    UserSessionModel userSession = session.sessions().createUserSession(realm, session.users().getUserByUsername(realm, "user1"), "user1", "127.0.0.2", "form", true, null, null);
    AuthenticatedClientSessionModel clientSession = createClientSession(session, client, userSession, "http://redirect", "state");
    UserSessionModel userSessionLoaded = session.sessions().getUserSession(realm, userSession.getId());
    AuthenticatedClientSessionModel clientSessionLoaded = userSessionLoaded.getAuthenticatedClientSessions().get(client.getId());
    Assert.assertNotNull(userSessionLoaded);
    Assert.assertNotNull(clientSessionLoaded);
    Assert.assertEquals(userSession.getId(), clientSessionLoaded.getUserSession().getId());
    Assert.assertEquals(1, userSessionLoaded.getAuthenticatedClientSessions().size());
}
Also used : RealmModel(org.keycloak.models.RealmModel) ClientModel(org.keycloak.models.ClientModel) UserSessionModel(org.keycloak.models.UserSessionModel) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) ModelTest(org.keycloak.testsuite.arquillian.annotation.ModelTest) ModelTest(org.keycloak.testsuite.arquillian.annotation.ModelTest) Test(org.junit.Test) AbstractTestRealmKeycloakTest(org.keycloak.testsuite.AbstractTestRealmKeycloakTest)

Example 19 with AuthenticatedClientSessionModel

use of org.keycloak.models.AuthenticatedClientSessionModel in project keycloak by keycloak.

the class AccountFormService method init.

public void init() {
    eventStore = session.getProvider(EventStoreProvider.class);
    account = session.getProvider(AccountProvider.class).setRealm(realm).setUriInfo(session.getContext().getUri()).setHttpHeaders(headers);
    AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm);
    if (authResult != null) {
        stateChecker = (String) session.getAttribute("state_checker");
        auth = new Auth(realm, authResult.getToken(), authResult.getUser(), client, authResult.getSession(), true);
        account.setStateChecker(stateChecker);
    }
    String requestOrigin = UriUtils.getOrigin(session.getContext().getUri().getBaseUri());
    String origin = headers.getRequestHeaders().getFirst("Origin");
    if (origin != null && !origin.equals("null") && !requestOrigin.equals(origin)) {
        throw new ForbiddenException();
    }
    if (!request.getHttpMethod().equals("GET")) {
        String referrer = headers.getRequestHeaders().getFirst("Referer");
        if (referrer != null && !requestOrigin.equals(UriUtils.getOrigin(referrer))) {
            throw new ForbiddenException();
        }
    }
    if (authResult != null) {
        UserSessionModel userSession = authResult.getSession();
        if (userSession != null) {
            AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId());
            if (clientSession == null) {
                clientSession = session.sessions().createClientSession(userSession.getRealm(), client, userSession);
            }
            auth.setClientSession(clientSession);
        }
        account.setUser(auth.getUser());
    }
    account.setFeatures(realm.isIdentityFederationEnabled(), eventStore != null && realm.isEventsEnabled(), true, Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION));
}
Also used : AuthenticationManager(org.keycloak.services.managers.AuthenticationManager) ForbiddenException(org.keycloak.services.ForbiddenException) UserSessionModel(org.keycloak.models.UserSessionModel) Auth(org.keycloak.services.managers.Auth) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) EventStoreProvider(org.keycloak.events.EventStoreProvider)

Example 20 with AuthenticatedClientSessionModel

use of org.keycloak.models.AuthenticatedClientSessionModel in project keycloak by keycloak.

the class ClientResource method toUserSessionRepresentation.

/**
 * Converts the specified {@link UserSessionModel} into a {@link UserSessionRepresentation}.
 *
 * @param userSession the model to be converted.
 * @return a reference to the constructed representation.
 */
private UserSessionRepresentation toUserSessionRepresentation(final UserSessionModel userSession) {
    UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(userSession);
    // Update lastSessionRefresh with the timestamp from clientSession
    Map.Entry<String, AuthenticatedClientSessionModel> result = userSession.getAuthenticatedClientSessions().entrySet().stream().filter(entry -> Objects.equals(client.getId(), entry.getKey())).findFirst().orElse(null);
    if (result != null) {
        rep.setLastAccess(Time.toMillis(result.getValue().getTimestamp()));
    }
    return rep;
}
Also used : UserSessionRepresentation(org.keycloak.representations.idm.UserSessionRepresentation) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

AuthenticatedClientSessionModel (org.keycloak.models.AuthenticatedClientSessionModel)59 UserSessionModel (org.keycloak.models.UserSessionModel)35 RealmModel (org.keycloak.models.RealmModel)25 ClientModel (org.keycloak.models.ClientModel)23 Test (org.junit.Test)16 AbstractTestRealmKeycloakTest (org.keycloak.testsuite.AbstractTestRealmKeycloakTest)13 UserModel (org.keycloak.models.UserModel)12 KeycloakSession (org.keycloak.models.KeycloakSession)11 ModelTest (org.keycloak.testsuite.arquillian.annotation.ModelTest)11 HashMap (java.util.HashMap)10 Map (java.util.Map)9 ClientSessionContext (org.keycloak.models.ClientSessionContext)9 LinkedList (java.util.LinkedList)8 DefaultClientSessionContext (org.keycloak.services.util.DefaultClientSessionContext)8 OAuthErrorException (org.keycloak.OAuthErrorException)6 VerificationException (org.keycloak.common.VerificationException)6 AccessToken (org.keycloak.representations.AccessToken)6 ClientPolicyException (org.keycloak.services.clientpolicy.ClientPolicyException)6 HashSet (java.util.HashSet)5 List (java.util.List)5