Search in sources :

Example 21 with KeycloakSession

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

the class LastSessionRefreshCrossDCTest method testLastSessionRefreshUpdate.

@Test
public void testLastSessionRefreshUpdate(@JmxInfinispanCacheStatistics(dc = DC.FIRST, managementPortProperty = "cache.server.management.port", cacheName = InfinispanConnectionProvider.USER_SESSION_CACHE_NAME) InfinispanStatistics sessionCacheDc1Stats, @JmxInfinispanCacheStatistics(dc = DC.SECOND, managementPortProperty = "cache.server.2.management.port", cacheName = InfinispanConnectionProvider.USER_SESSION_CACHE_NAME) InfinispanStatistics sessionCacheDc2Stats, @JmxInfinispanCacheStatistics(dc = DC.FIRST, managementPortProperty = "cache.server.management.port", cacheName = InfinispanConnectionProvider.CLIENT_SESSION_CACHE_NAME) InfinispanStatistics clientSessionCacheDc1Stats, @JmxInfinispanCacheStatistics(dc = DC.SECOND, managementPortProperty = "cache.server.2.management.port", cacheName = InfinispanConnectionProvider.CLIENT_SESSION_CACHE_NAME) InfinispanStatistics clientSessionCacheDc2Stats) {
    // Set the infinispan testTimeService on all started auth servers
    setInfinispanTestTimeServiceOnAllStartedAuthServers();
    try {
        // Ensure to remove all current sessions and offline sessions
        setTimeOffset(10000000);
        getTestingClientForStartedNodeInDc(0).testing("test").removeExpired("test");
        getTestingClientForStartedNodeInDc(1).testing("test").removeExpired("test");
        setTimeOffset(0);
        sessionCacheDc1Stats.reset();
        sessionCacheDc2Stats.reset();
        clientSessionCacheDc1Stats.reset();
        clientSessionCacheDc2Stats.reset();
        // Disable DC2 on loadbalancer
        disableDcOnLoadBalancer(DC.SECOND);
        // Get statistics
        AtomicLong sessionStoresDc1 = new AtomicLong(getStores(sessionCacheDc1Stats));
        AtomicLong sessionStoresDc2 = new AtomicLong(getStores(sessionCacheDc2Stats));
        AtomicLong clientSessionStoresDc1 = new AtomicLong(getStores(clientSessionCacheDc1Stats));
        AtomicLong clientSessionStoresDc2 = new AtomicLong(getStores(clientSessionCacheDc2Stats));
        AtomicInteger lsrDc1 = new AtomicInteger(-1);
        AtomicInteger lsrDc2 = new AtomicInteger(-1);
        // Login
        OAuthClient.AuthorizationEndpointResponse response1 = oauth.doLogin("test-user@localhost", "password");
        String code = response1.getCode();
        OAuthClient.AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code, "password");
        Assert.assertNotNull(tokenResponse.getAccessToken());
        String sessionId = oauth.verifyToken(tokenResponse.getAccessToken()).getSessionState();
        String refreshToken1 = tokenResponse.getRefreshToken();
        // Assert statistics - sessions created on both DCs and created on remoteCaches too
        assertStatistics("After session created", sessionId, sessionCacheDc1Stats, sessionCacheDc2Stats, clientSessionCacheDc1Stats, clientSessionCacheDc2Stats, sessionStoresDc1, sessionStoresDc2, clientSessionStoresDc1, clientSessionStoresDc2, lsrDc1, lsrDc2, true, true, true, false);
        // Set time offset
        setTimeOffset(100);
        // refresh token on DC1
        tokenResponse = oauth.doRefreshTokenRequest(refreshToken1, "password");
        String refreshToken2 = tokenResponse.getRefreshToken();
        Assert.assertNotNull(refreshToken2);
        // Assert statistics - sessions updated on both DC1 and DC2. RemoteCaches not updated
        assertStatistics("After refresh at time 100", sessionId, sessionCacheDc1Stats, sessionCacheDc2Stats, clientSessionCacheDc1Stats, clientSessionCacheDc2Stats, sessionStoresDc1, sessionStoresDc2, clientSessionStoresDc1, clientSessionStoresDc2, lsrDc1, lsrDc2, true, true, false, false);
        // Set time offset
        setTimeOffset(110);
        // refresh token on DC1
        tokenResponse = oauth.doRefreshTokenRequest(refreshToken1, "password");
        String refreshToken3 = tokenResponse.getRefreshToken();
        Assert.assertNotNull(refreshToken3);
        // Assert statistics - sessions updated just on DC1.
        // Update of DC2 is postponed (It's just 10 seconds since last message). RemoteCaches not updated
        assertStatistics("After refresh at time 110", sessionId, sessionCacheDc1Stats, sessionCacheDc2Stats, clientSessionCacheDc1Stats, clientSessionCacheDc2Stats, sessionStoresDc1, sessionStoresDc2, clientSessionStoresDc1, clientSessionStoresDc2, lsrDc1, lsrDc2, true, false, false, false);
        // 31 minutes after "100". Session should be still valid and not yet expired (RefreshToken will be invalid due the expiration on the JWT itself. Hence not testing refresh here)
        setTimeOffset(1960);
        boolean sessionValid = getTestingClientForStartedNodeInDc(1).server("test").fetch((KeycloakSession session) -> {
            RealmModel realm = session.realms().getRealmByName("test");
            UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
            return AuthenticationManager.isSessionValid(realm, userSession);
        }, Boolean.class);
        Assert.assertTrue(sessionValid);
        getTestingClientForStartedNodeInDc(1).testing("test").removeExpired("test");
        // Assert statistics - nothing was updated. No refresh happened and nothing was cleared during "removeExpired"
        assertStatistics("After checking valid at time 1960", sessionId, sessionCacheDc1Stats, sessionCacheDc2Stats, clientSessionCacheDc1Stats, clientSessionCacheDc2Stats, sessionStoresDc1, sessionStoresDc2, clientSessionStoresDc1, clientSessionStoresDc2, lsrDc1, lsrDc2, false, false, false, false);
        // 35 minutes after "100". Session not valid and will be expired by the cleaner
        setTimeOffset(2200);
        sessionValid = getTestingClientForStartedNodeInDc(1).server("test").fetch((KeycloakSession session) -> {
            RealmModel realm = session.realms().getRealmByName("test");
            UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
            return AuthenticationManager.isSessionValid(realm, userSession);
        }, Boolean.class);
        Assert.assertFalse(sessionValid);
        // 2000 seconds after the previous. This should ensure that session would be expired from the cache due the invalid maxIdle.
        // Previous read at time 2200 "refreshed" the maxIdle in the infinispan cache. This shouldn't happen in reality as an attempt to call refreshToken request on invalid session does backchannelLogout
        setTimeOffset(4200);
        getTestingClientForStartedNodeInDc(1).testing("test").removeExpired("test");
        // Session should be removed on both DCs
        try {
            getTestingClientForStartedNodeInDc(0).testing("test").getLastSessionRefresh("test", sessionId, false);
            Assert.fail("It wasn't expected to find the session " + sessionId);
        } catch (NotFoundException nfe) {
        // Expected
        }
        try {
            getTestingClientForStartedNodeInDc(1).testing("test").getLastSessionRefresh("test", sessionId, false);
            Assert.fail("It wasn't expected to find the session " + sessionId);
        } catch (NotFoundException nfe) {
        // Expected
        }
    } finally {
        // Revert time service
        revertInfinispanTestTimeServiceOnAllStartedAuthServers();
    }
}
Also used : RealmModel(org.keycloak.models.RealmModel) AtomicLong(java.util.concurrent.atomic.AtomicLong) UserSessionModel(org.keycloak.models.UserSessionModel) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) OAuthClient(org.keycloak.testsuite.util.OAuthClient) KeycloakSession(org.keycloak.models.KeycloakSession) NotFoundException(javax.ws.rs.NotFoundException) Test(org.junit.Test)

Example 22 with KeycloakSession

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

the class JpaRealmProvider method removeClient.

@Override
public boolean removeClient(RealmModel realm, String id) {
    logger.tracef("removeClient(%s, %s)%s", realm, id, getShortStackTrace());
    final ClientModel client = getClientById(realm, id);
    if (client == null)
        return false;
    session.users().preRemove(realm, client);
    session.roles().removeRoles(client);
    ClientEntity clientEntity = em.find(ClientEntity.class, id, LockModeType.PESSIMISTIC_WRITE);
    session.getKeycloakSessionFactory().publish(new ClientModel.ClientRemovedEvent() {

        @Override
        public ClientModel getClient() {
            return client;
        }

        @Override
        public KeycloakSession getKeycloakSession() {
            return session;
        }
    });
    int countRemoved = em.createNamedQuery("deleteClientScopeClientMappingByClient").setParameter("clientId", clientEntity.getId()).executeUpdate();
    // i have no idea why, but this needs to come before deleteScopeMapping
    em.remove(clientEntity);
    try {
        em.flush();
    } catch (RuntimeException e) {
        logger.errorv("Unable to delete client entity: {0} from realm {1}", client.getClientId(), realm.getName());
        throw e;
    }
    return true;
}
Also used : ClientModel(org.keycloak.models.ClientModel) ClientEntity(org.keycloak.models.jpa.entities.ClientEntity) KeycloakSession(org.keycloak.models.KeycloakSession)

Example 23 with KeycloakSession

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

the class RegistrationUserCreation method success.

@Override
public void success(FormContext context) {
    MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
    String email = formData.getFirst(UserModel.EMAIL);
    String username = formData.getFirst(UserModel.USERNAME);
    if (context.getRealm().isRegistrationEmailAsUsername()) {
        username = email;
    }
    context.getEvent().detail(Details.USERNAME, username).detail(Details.REGISTER_METHOD, "form").detail(Details.EMAIL, email);
    KeycloakSession session = context.getSession();
    UserProfileProvider profileProvider = session.getProvider(UserProfileProvider.class);
    UserProfile profile = profileProvider.create(UserProfileContext.REGISTRATION_USER_CREATION, formData);
    UserModel user = profile.create();
    user.setEnabled(true);
    context.setUser(user);
    context.getAuthenticationSession().setClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM, username);
    context.getEvent().user(user);
    context.getEvent().success();
    context.newEvent().event(EventType.LOGIN);
    context.getEvent().client(context.getAuthenticationSession().getClient().getClientId()).detail(Details.REDIRECT_URI, context.getAuthenticationSession().getRedirectUri()).detail(Details.AUTH_METHOD, context.getAuthenticationSession().getProtocol());
    String authType = context.getAuthenticationSession().getAuthNote(Details.AUTH_TYPE);
    if (authType != null) {
        context.getEvent().detail(Details.AUTH_TYPE, authType);
    }
}
Also used : UserModel(org.keycloak.models.UserModel) UserProfile(org.keycloak.userprofile.UserProfile) KeycloakSession(org.keycloak.models.KeycloakSession) UserProfileProvider(org.keycloak.userprofile.UserProfileProvider)

Example 24 with KeycloakSession

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

the class RegistrationUserCreation method validate.

@Override
public void validate(ValidationContext context) {
    MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
    context.getEvent().detail(Details.REGISTER_METHOD, "form");
    KeycloakSession session = context.getSession();
    UserProfileProvider profileProvider = session.getProvider(UserProfileProvider.class);
    UserProfile profile = profileProvider.create(UserProfileContext.REGISTRATION_USER_CREATION, formData);
    String email = profile.getAttributes().getFirstValue(UserModel.EMAIL);
    String username = profile.getAttributes().getFirstValue(UserModel.USERNAME);
    String firstName = profile.getAttributes().getFirstValue(UserModel.FIRST_NAME);
    String lastName = profile.getAttributes().getFirstValue(UserModel.LAST_NAME);
    context.getEvent().detail(Details.EMAIL, email);
    context.getEvent().detail(Details.USERNAME, username);
    context.getEvent().detail(Details.FIRST_NAME, firstName);
    context.getEvent().detail(Details.LAST_NAME, lastName);
    if (context.getRealm().isRegistrationEmailAsUsername()) {
        context.getEvent().detail(Details.USERNAME, email);
    }
    try {
        profile.validate();
    } catch (ValidationException pve) {
        List<FormMessage> errors = Validation.getFormErrorsFromValidation(pve.getErrors());
        if (pve.hasError(Messages.EMAIL_EXISTS)) {
            context.error(Errors.EMAIL_IN_USE);
        } else if (pve.hasError(Messages.MISSING_EMAIL, Messages.MISSING_USERNAME, Messages.INVALID_EMAIL)) {
            context.error(Errors.INVALID_REGISTRATION);
        } else if (pve.hasError(Messages.USERNAME_EXISTS)) {
            context.error(Errors.USERNAME_IN_USE);
        }
        context.validationError(formData, errors);
        return;
    }
    context.success();
}
Also used : ValidationException(org.keycloak.userprofile.ValidationException) UserProfile(org.keycloak.userprofile.UserProfile) KeycloakSession(org.keycloak.models.KeycloakSession) UserProfileProvider(org.keycloak.userprofile.UserProfileProvider) List(java.util.List)

Example 25 with KeycloakSession

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

the class DeclarativeUserProfileProvider method requestedScopePredicate.

/**
 * Method used for predicate which returns true if any of the configuredScopes is requested in current auth flow.
 *
 * @param context to get current auth flow from
 * @param configuredScopes to be evaluated
 * @return
 */
private static boolean requestedScopePredicate(AttributeContext context, Set<String> configuredScopes) {
    KeycloakSession session = context.getSession();
    AuthenticationSessionModel authenticationSession = session.getContext().getAuthenticationSession();
    if (authenticationSession == null) {
        return false;
    }
    String requestedScopesString = authenticationSession.getClientNote(OIDCLoginProtocol.SCOPE_PARAM);
    ClientModel client = authenticationSession.getClient();
    return getRequestedClientScopes(requestedScopesString, client).map((csm) -> csm.getName()).anyMatch(configuredScopes::contains);
}
Also used : ClientModel(org.keycloak.models.ClientModel) UPConfigUtils(org.keycloak.userprofile.config.UPConfigUtils) Profile(org.keycloak.common.Profile) ProviderConfigProperty(org.keycloak.provider.ProviderConfigProperty) HashMap(java.util.HashMap) Config(org.keycloak.Config) Messages(org.keycloak.services.messages.Messages) TokenManager.getRequestedClientScopes(org.keycloak.protocol.oidc.TokenManager.getRequestedClientScopes) ArrayList(java.util.ArrayList) AmphibianProviderFactory(org.keycloak.component.AmphibianProviderFactory) AbstractSimpleValidator(org.keycloak.validate.AbstractSimpleValidator) UserModel(org.keycloak.models.UserModel) ByteArrayInputStream(java.io.ByteArrayInputStream) Map(java.util.Map) DeclarativeUserProfileModel(org.keycloak.userprofile.config.DeclarativeUserProfileModel) UPConfigUtils.readConfig(org.keycloak.userprofile.config.UPConfigUtils.readConfig) ComponentModel(org.keycloak.component.ComponentModel) AttributeRequiredByMetadataValidator(org.keycloak.userprofile.validator.AttributeRequiredByMetadataValidator) UPGroup(org.keycloak.userprofile.config.UPGroup) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RealmModel(org.keycloak.models.RealmModel) UPAttributeSelector(org.keycloak.userprofile.config.UPAttributeSelector) ImmutableAttributeValidator(org.keycloak.userprofile.validator.ImmutableAttributeValidator) ValidatorConfig(org.keycloak.validate.ValidatorConfig) UPAttribute(org.keycloak.userprofile.config.UPAttribute) Predicate(java.util.function.Predicate) UPAttributeRequired(org.keycloak.userprofile.config.UPAttributeRequired) Set(java.util.Set) KeycloakSession(org.keycloak.models.KeycloakSession) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) UPConfig(org.keycloak.userprofile.config.UPConfig) List(java.util.List) ObjectUtil.isBlank(org.keycloak.common.util.ObjectUtil.isBlank) BlankAttributeValidator(org.keycloak.userprofile.validator.BlankAttributeValidator) OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol) UPAttributePermissions(org.keycloak.userprofile.config.UPAttributePermissions) EmailValidator(org.keycloak.validate.validators.EmailValidator) MultivaluedHashMap(org.keycloak.common.util.MultivaluedHashMap) Collections(java.util.Collections) ComponentValidationException(org.keycloak.component.ComponentValidationException) ClientModel(org.keycloak.models.ClientModel) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) KeycloakSession(org.keycloak.models.KeycloakSession)

Aggregations

KeycloakSession (org.keycloak.models.KeycloakSession)189 RealmModel (org.keycloak.models.RealmModel)136 UserModel (org.keycloak.models.UserModel)78 Test (org.junit.Test)76 ModelTest (org.keycloak.testsuite.arquillian.annotation.ModelTest)61 ClientModel (org.keycloak.models.ClientModel)58 AbstractTestRealmKeycloakTest (org.keycloak.testsuite.AbstractTestRealmKeycloakTest)53 List (java.util.List)34 AtomicReference (java.util.concurrent.atomic.AtomicReference)22 Collectors (java.util.stream.Collectors)21 IOException (java.io.IOException)20 Map (java.util.Map)19 UserSessionModel (org.keycloak.models.UserSessionModel)19 ArrayList (java.util.ArrayList)18 ClientScopeModel (org.keycloak.models.ClientScopeModel)18 RoleModel (org.keycloak.models.RoleModel)18 Set (java.util.Set)16 RealmManager (org.keycloak.services.managers.RealmManager)16 HashMap (java.util.HashMap)14 RealmRepresentation (org.keycloak.representations.idm.RealmRepresentation)14