Search in sources :

Example 21 with KeycloakSessionFactory

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

the class Validators method validatorFactory.

/**
 * Look-up for a built-in or registered {@link ValidatorFactory} with the given validatorId.
 * <p>
 * This is intended for users who want to dynamically create new {@link Validator} instances, validate
 * {@link ValidatorConfig} configurations or create default configurations for a {@link Validator}.
 *
 * @param session the {@link KeycloakSession}
 * @param id      the id of the validator
 * @return the {@link Validator} or {@literal null}
 */
public static ValidatorFactory validatorFactory(KeycloakSession session, String id) {
    // Fast-path for internal Validators
    ValidatorFactory factory = getInternalValidatorFactoryById(id);
    if (factory != null) {
        return factory;
    }
    if (session == null) {
        return null;
    }
    // Lookup factory in registry
    KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
    return (ValidatorFactory) sessionFactory.getProviderFactory(Validator.class, id);
}
Also used : KeycloakSessionFactory(org.keycloak.models.KeycloakSessionFactory) NotEmptyValidator(org.keycloak.validate.validators.NotEmptyValidator) LengthValidator(org.keycloak.validate.validators.LengthValidator) UriValidator(org.keycloak.validate.validators.UriValidator) LocalDateValidator(org.keycloak.validate.validators.LocalDateValidator) OptionsValidator(org.keycloak.validate.validators.OptionsValidator) DoubleValidator(org.keycloak.validate.validators.DoubleValidator) PatternValidator(org.keycloak.validate.validators.PatternValidator) IntegerValidator(org.keycloak.validate.validators.IntegerValidator) ValidatorConfigValidator(org.keycloak.validate.validators.ValidatorConfigValidator) NotBlankValidator(org.keycloak.validate.validators.NotBlankValidator) EmailValidator(org.keycloak.validate.validators.EmailValidator)

Example 22 with KeycloakSessionFactory

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

the class ConcurrentTransactionsTest method persistClient.

@Test
@ModelTest
public void persistClient(KeycloakSession session) {
    final ClientModel[] client = { null };
    AtomicReference<String> clientDBIdAtomic = new AtomicReference<>();
    AtomicReference<Exception> exceptionHolder = new AtomicReference<>();
    try {
        KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionSetup) -> {
            RealmModel realm = sessionSetup.realms().getRealm("test");
            sessionSetup.users().addUser(realm, "user1").setEmail("user1@localhost");
            sessionSetup.users().addUser(realm, "user2").setEmail("user2@localhost");
            realm = sessionSetup.realms().createRealm("original");
            RoleModel defaultRole = sessionSetup.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName());
            realm.setDefaultRole(defaultRole);
            client[0] = sessionSetup.clients().addClient(realm, "client");
            client[0].setSecret("old");
        });
        KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession session1) -> {
            String clientDBId = client[0].getId();
            clientDBIdAtomic.set(clientDBId);
            final KeycloakSessionFactory sessionFactory = session1.getKeycloakSessionFactory();
            final CountDownLatch transactionsCounter = new CountDownLatch(2);
            final CountDownLatch readLatch = new CountDownLatch(1);
            final CountDownLatch updateLatch = new CountDownLatch(1);
            Thread thread1 = new Thread(() -> {
                KeycloakModelUtils.runJobInTransaction(sessionFactory, session11 -> {
                    try {
                        KeycloakSession currentSession = session11;
                        // Wait until transaction in both threads started
                        transactionsCounter.countDown();
                        logger.info("transaction1 started");
                        if (!transactionsCounter.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
                            throw new IllegalStateException("Timeout when waiting for transactionsCounter latch in thread1");
                        }
                        // Read client
                        RealmModel realm1 = currentSession.realms().getRealmByName("original");
                        ClientModel client1 = currentSession.clients().getClientByClientId(realm1, "client");
                        logger.info("transaction1: Read client finished");
                        readLatch.countDown();
                        // Wait until thread2 updates client and commits
                        if (!updateLatch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
                            throw new IllegalStateException("Timeout when waiting for updateLatch");
                        }
                        logger.info("transaction1: Going to read client again");
                        client1 = currentSession.clients().getClientByClientId(realm1, "client");
                        logger.info("transaction1: secret: " + client1.getSecret());
                    } catch (Exception e) {
                        exceptionHolder.set(e);
                        throw new RuntimeException(e);
                    }
                });
            });
            Thread thread2 = new Thread(() -> {
                KeycloakModelUtils.runJobInTransaction(sessionFactory, session22 -> {
                    try {
                        KeycloakSession currentSession = session22;
                        // Wait until transaction in both threads started
                        transactionsCounter.countDown();
                        logger.info("transaction2 started");
                        if (!transactionsCounter.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
                            throw new IllegalStateException("Timeout when waiting for transactionsCounter latch in thread2");
                        }
                        // Wait until reader thread reads the client
                        if (!readLatch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
                            throw new IllegalStateException("Timeout when waiting for readLatch");
                        }
                        logger.info("transaction2: Going to update client secret");
                        RealmModel realm12 = currentSession.realms().getRealmByName("original");
                        ClientModel client12 = currentSession.clients().getClientByClientId(realm12, "client");
                        client12.setSecret("new");
                    } catch (Exception e) {
                        exceptionHolder.set(e);
                        throw new RuntimeException(e);
                    }
                });
                logger.info("transaction2: commited");
                updateLatch.countDown();
            });
            thread1.start();
            thread2.start();
            try {
                thread1.join();
                thread2.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (exceptionHolder.get() != null) {
                Assert.fail("Some thread thrown an exception. See the log for the details");
            }
            logger.info("after thread join");
        });
        KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession session2) -> {
            RealmModel realm = session2.realms().getRealmByName("original");
            String clientDBId = clientDBIdAtomic.get();
            ClientModel clientFromCache = session2.clients().getClientById(realm, clientDBId);
            ClientModel clientFromDB = session2.getProvider(ClientProvider.class).getClientById(realm, clientDBId);
            logger.info("SECRET FROM DB : " + clientFromDB.getSecret());
            logger.info("SECRET FROM CACHE : " + clientFromCache.getSecret());
            Assert.assertEquals("new", clientFromDB.getSecret());
            Assert.assertEquals("new", clientFromCache.getSecret());
            session2.sessions().removeUserSessions(realm);
        });
    } finally {
        tearDownRealm(session, "user1", "user2");
    }
}
Also used : ClientProvider(org.keycloak.models.ClientProvider) AtomicReference(java.util.concurrent.atomic.AtomicReference) RoleModel(org.keycloak.models.RoleModel) KeycloakSessionFactory(org.keycloak.models.KeycloakSessionFactory) CountDownLatch(java.util.concurrent.CountDownLatch) RealmModel(org.keycloak.models.RealmModel) ClientModel(org.keycloak.models.ClientModel) KeycloakSession(org.keycloak.models.KeycloakSession) ModelTest(org.keycloak.testsuite.arquillian.annotation.ModelTest) ModelTest(org.keycloak.testsuite.arquillian.annotation.ModelTest) Test(org.junit.Test) AbstractTestRealmKeycloakTest(org.keycloak.testsuite.AbstractTestRealmKeycloakTest)

Example 23 with KeycloakSessionFactory

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

the class ConcurrentTransactionsTest method removeUserAttribute.

// KEYCLOAK-3296 , KEYCLOAK-3494
@Test
@ModelTest
public void removeUserAttribute(KeycloakSession session) throws Exception {
    try {
        KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionSet) -> {
            RealmModel realm = sessionSet.realms().createRealm("original");
            realm.setDefaultRole(sessionSet.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName()));
            UserModel john = sessionSet.users().addUser(realm, "john");
            john.setSingleAttribute("foo", "val1");
            UserModel john2 = sessionSet.users().addUser(realm, "john2");
            john2.setAttribute("foo", Arrays.asList("val1", "val2"));
        });
        KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession session2) -> {
            final KeycloakSessionFactory sessionFactory = session2.getKeycloakSessionFactory();
            AtomicReference<Exception> reference = new AtomicReference<>();
            final CountDownLatch readAttrLatch = new CountDownLatch(2);
            Runnable runnable = () -> {
                try {
                    KeycloakModelUtils.runJobInTransaction(sessionFactory, session1 -> {
                        try {
                            // Read user attribute
                            RealmModel realm = session1.realms().getRealmByName("original");
                            UserModel john = session1.users().getUserByUsername(realm, "john");
                            String attrVal = john.getFirstAttribute("foo");
                            UserModel john2 = session1.users().getUserByUsername(realm, "john2");
                            String attrVal2 = john2.getFirstAttribute("foo");
                            // Wait until it's read in both threads
                            readAttrLatch.countDown();
                            readAttrLatch.await();
                            // KEYCLOAK-3296 : Remove user attribute in both threads
                            john.removeAttribute("foo");
                            // KEYCLOAK-3494 : Set single attribute in both threads
                            john2.setSingleAttribute("foo", "bar");
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    });
                } catch (Exception e) {
                    reference.set(e);
                    throw new RuntimeException(e);
                } finally {
                    readAttrLatch.countDown();
                }
            };
            Thread thread1 = new Thread(runnable);
            Thread thread2 = new Thread(runnable);
            thread1.start();
            thread2.start();
            try {
                thread1.join();
                thread2.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            logger.info("removeUserAttribute: after thread join");
            if (reference.get() != null) {
                Assert.fail("Exception happened in some of threads. Details: " + reference.get().getMessage());
            }
        });
    } finally {
        tearDownRealm(session, "john", "john2");
    }
}
Also used : ClientModel(org.keycloak.models.ClientModel) ModelTest(org.keycloak.testsuite.arquillian.annotation.ModelTest) UserManager(org.keycloak.models.UserManager) Arrays(java.util.Arrays) RealmModel(org.keycloak.models.RealmModel) AuthServerContainerExclude(org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude) KeycloakModelUtils(org.keycloak.models.utils.KeycloakModelUtils) Logger(org.jboss.logging.Logger) ClientProvider(org.keycloak.models.ClientProvider) Constants(org.keycloak.models.Constants) KeycloakSession(org.keycloak.models.KeycloakSession) Test(org.junit.Test) RoleModel(org.keycloak.models.RoleModel) AbstractTestRealmKeycloakTest(org.keycloak.testsuite.AbstractTestRealmKeycloakTest) AtomicReference(java.util.concurrent.atomic.AtomicReference) RealmRepresentation(org.keycloak.representations.idm.RealmRepresentation) TimeUnit(java.util.concurrent.TimeUnit) CountDownLatch(java.util.concurrent.CountDownLatch) UserModel(org.keycloak.models.UserModel) KeycloakSessionFactory(org.keycloak.models.KeycloakSessionFactory) Matchers.nullValue(org.hamcrest.Matchers.nullValue) Matchers.is(org.hamcrest.Matchers.is) Assert(org.junit.Assert) AuthServer(org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer) AtomicReference(java.util.concurrent.atomic.AtomicReference) KeycloakSessionFactory(org.keycloak.models.KeycloakSessionFactory) CountDownLatch(java.util.concurrent.CountDownLatch) RealmModel(org.keycloak.models.RealmModel) UserModel(org.keycloak.models.UserModel) KeycloakSession(org.keycloak.models.KeycloakSession) ModelTest(org.keycloak.testsuite.arquillian.annotation.ModelTest) ModelTest(org.keycloak.testsuite.arquillian.annotation.ModelTest) Test(org.junit.Test) AbstractTestRealmKeycloakTest(org.keycloak.testsuite.AbstractTestRealmKeycloakTest)

Example 24 with KeycloakSessionFactory

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

the class InfinispanUserLoginFailureProviderFactory method registerClusterListeners.

protected void registerClusterListeners(KeycloakSession session) {
    KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
    ClusterProvider cluster = session.getProvider(ClusterProvider.class);
    cluster.registerListener(REALM_REMOVED_SESSION_EVENT, new AbstractUserSessionClusterListener<RealmRemovedSessionEvent, UserLoginFailureProvider>(sessionFactory, UserLoginFailureProvider.class) {

        @Override
        protected void eventReceived(KeycloakSession session, UserLoginFailureProvider provider, RealmRemovedSessionEvent sessionEvent) {
            if (provider instanceof InfinispanUserLoginFailureProvider) {
                ((InfinispanUserLoginFailureProvider) provider).removeAllLocalUserLoginFailuresEvent(sessionEvent.getRealmId());
            }
        }
    });
    cluster.registerListener(REMOVE_ALL_LOGIN_FAILURES_EVENT, new AbstractUserSessionClusterListener<RemoveAllUserLoginFailuresEvent, UserLoginFailureProvider>(sessionFactory, UserLoginFailureProvider.class) {

        @Override
        protected void eventReceived(KeycloakSession session, UserLoginFailureProvider provider, RemoveAllUserLoginFailuresEvent sessionEvent) {
            if (provider instanceof InfinispanUserLoginFailureProvider) {
                ((InfinispanUserLoginFailureProvider) provider).removeAllLocalUserLoginFailuresEvent(sessionEvent.getRealmId());
            }
        }
    });
    log.debug("Registered cluster listeners");
}
Also used : RemoveAllUserLoginFailuresEvent(org.keycloak.models.sessions.infinispan.events.RemoveAllUserLoginFailuresEvent) ClusterProvider(org.keycloak.cluster.ClusterProvider) KeycloakSession(org.keycloak.models.KeycloakSession) KeycloakSessionFactory(org.keycloak.models.KeycloakSessionFactory) RealmRemovedSessionEvent(org.keycloak.models.sessions.infinispan.events.RealmRemovedSessionEvent) UserLoginFailureProvider(org.keycloak.models.UserLoginFailureProvider)

Example 25 with KeycloakSessionFactory

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

the class IdentityBrokerService method authenticated.

public Response authenticated(BrokeredIdentityContext context) {
    IdentityProviderModel identityProviderConfig = context.getIdpConfig();
    AuthenticationSessionModel authenticationSession = context.getAuthenticationSession();
    String providerId = identityProviderConfig.getAlias();
    if (!identityProviderConfig.isStoreToken()) {
        if (isDebugEnabled()) {
            logger.debugf("Token will not be stored for identity provider [%s].", providerId);
        }
        context.setToken(null);
    }
    StatusResponseType loginResponse = (StatusResponseType) context.getContextData().get(SAMLEndpoint.SAML_LOGIN_RESPONSE);
    if (loginResponse != null) {
        for (Iterator<SamlAuthenticationPreprocessor> it = SamlSessionUtils.getSamlAuthenticationPreprocessorIterator(session); it.hasNext(); ) {
            loginResponse = it.next().beforeProcessingLoginResponse(loginResponse, authenticationSession);
        }
    }
    session.getContext().setClient(authenticationSession.getClient());
    context.getIdp().preprocessFederatedIdentity(session, realmModel, context);
    KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
    realmModel.getIdentityProviderMappersByAliasStream(context.getIdpConfig().getAlias()).forEach(mapper -> {
        IdentityProviderMapper target = (IdentityProviderMapper) sessionFactory.getProviderFactory(IdentityProviderMapper.class, mapper.getIdentityProviderMapper());
        target.preprocessFederatedIdentity(session, realmModel, mapper, context);
    });
    FederatedIdentityModel federatedIdentityModel = new FederatedIdentityModel(providerId, context.getId(), context.getUsername(), context.getToken());
    this.event.event(EventType.IDENTITY_PROVIDER_LOGIN).detail(Details.REDIRECT_URI, authenticationSession.getRedirectUri()).detail(Details.IDENTITY_PROVIDER, providerId).detail(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername());
    UserModel federatedUser = this.session.users().getUserByFederatedIdentity(this.realmModel, federatedIdentityModel);
    boolean shouldMigrateId = false;
    // try to find the user using legacy ID
    if (federatedUser == null && context.getLegacyId() != null) {
        federatedIdentityModel = new FederatedIdentityModel(federatedIdentityModel, context.getLegacyId());
        federatedUser = this.session.users().getUserByFederatedIdentity(this.realmModel, federatedIdentityModel);
        shouldMigrateId = true;
    }
    // Check if federatedUser is already authenticated (this means linking social into existing federatedUser account)
    UserSessionModel userSession = new AuthenticationSessionManager(session).getUserSession(authenticationSession);
    if (shouldPerformAccountLinking(authenticationSession, userSession, providerId)) {
        return performAccountLinking(authenticationSession, userSession, context, federatedIdentityModel, federatedUser);
    }
    if (federatedUser == null) {
        logger.debugf("Federated user not found for provider '%s' and broker username '%s'", providerId, context.getUsername());
        String username = context.getModelUsername();
        if (username == null) {
            if (this.realmModel.isRegistrationEmailAsUsername() && !Validation.isBlank(context.getEmail())) {
                username = context.getEmail();
            } else if (context.getUsername() == null) {
                username = context.getIdpConfig().getAlias() + "." + context.getId();
            } else {
                username = context.getUsername();
            }
        }
        username = username.trim();
        context.setModelUsername(username);
        SerializedBrokeredIdentityContext ctx0 = SerializedBrokeredIdentityContext.readFromAuthenticationSession(authenticationSession, AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE);
        if (ctx0 != null) {
            SerializedBrokeredIdentityContext ctx1 = SerializedBrokeredIdentityContext.serialize(context);
            ctx1.saveToAuthenticationSession(authenticationSession, AbstractIdpAuthenticator.NESTED_FIRST_BROKER_CONTEXT);
            logger.warnv("Nested first broker flow detected: {0} -> {1}", ctx0.getIdentityProviderId(), ctx1.getIdentityProviderId());
            logger.debug("Resuming last execution");
            URI redirect = new AuthenticationFlowURLHelper(session, realmModel, session.getContext().getUri()).getLastExecutionUrl(authenticationSession);
            return Response.status(Status.FOUND).location(redirect).build();
        }
        logger.debug("Redirecting to flow for firstBrokerLogin");
        boolean forwardedPassiveLogin = "true".equals(authenticationSession.getAuthNote(AuthenticationProcessor.FORWARDED_PASSIVE_LOGIN));
        // Redirect to firstBrokerLogin after successful login and ensure that previous authentication state removed
        AuthenticationProcessor.resetFlow(authenticationSession, LoginActionsService.FIRST_BROKER_LOGIN_PATH);
        // Set the FORWARDED_PASSIVE_LOGIN note (if needed) after resetting the session so it is not lost.
        if (forwardedPassiveLogin) {
            authenticationSession.setAuthNote(AuthenticationProcessor.FORWARDED_PASSIVE_LOGIN, "true");
        }
        SerializedBrokeredIdentityContext ctx = SerializedBrokeredIdentityContext.serialize(context);
        ctx.saveToAuthenticationSession(authenticationSession, AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE);
        URI redirect = LoginActionsService.firstBrokerLoginProcessor(session.getContext().getUri()).queryParam(Constants.CLIENT_ID, authenticationSession.getClient().getClientId()).queryParam(Constants.TAB_ID, authenticationSession.getTabId()).build(realmModel.getName());
        return Response.status(302).location(redirect).build();
    } else {
        Response response = validateUser(authenticationSession, federatedUser, realmModel);
        if (response != null) {
            return response;
        }
        updateFederatedIdentity(context, federatedUser);
        if (shouldMigrateId) {
            migrateFederatedIdentityId(context, federatedUser);
        }
        authenticationSession.setAuthenticatedUser(federatedUser);
        return finishOrRedirectToPostBrokerLogin(authenticationSession, context, false);
    }
}
Also used : AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) UserSessionModel(org.keycloak.models.UserSessionModel) FederatedIdentityModel(org.keycloak.models.FederatedIdentityModel) AuthenticationFlowURLHelper(org.keycloak.services.util.AuthenticationFlowURLHelper) IdentityProviderModel(org.keycloak.models.IdentityProviderModel) SerializedBrokeredIdentityContext(org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext) KeycloakSessionFactory(org.keycloak.models.KeycloakSessionFactory) URI(java.net.URI) StatusResponseType(org.keycloak.dom.saml.v2.protocol.StatusResponseType) UserModel(org.keycloak.models.UserModel) AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) Response(javax.ws.rs.core.Response) ErrorResponse(org.keycloak.services.ErrorResponse) IdentityProviderMapper(org.keycloak.broker.provider.IdentityProviderMapper) SamlAuthenticationPreprocessor(org.keycloak.protocol.saml.preprocessor.SamlAuthenticationPreprocessor)

Aggregations

KeycloakSessionFactory (org.keycloak.models.KeycloakSessionFactory)33 KeycloakSession (org.keycloak.models.KeycloakSession)11 RealmModel (org.keycloak.models.RealmModel)11 Test (org.junit.Test)10 UserModel (org.keycloak.models.UserModel)9 SynchronizationResult (org.keycloak.storage.user.SynchronizationResult)9 UserStorageSyncManager (org.keycloak.services.managers.UserStorageSyncManager)8 ComponentModel (org.keycloak.component.ComponentModel)7 IdentityProviderMapper (org.keycloak.broker.provider.IdentityProviderMapper)5 ClusterProvider (org.keycloak.cluster.ClusterProvider)5 FederatedIdentityModel (org.keycloak.models.FederatedIdentityModel)5 LDAPObject (org.keycloak.storage.ldap.idm.model.LDAPObject)5 HashMap (java.util.HashMap)4 Logger (org.jboss.logging.Logger)4 KeycloakModelUtils (org.keycloak.models.utils.KeycloakModelUtils)4 UserStorageProviderModel (org.keycloak.storage.UserStorageProviderModel)4 Arrays (java.util.Arrays)3 LinkedList (java.util.LinkedList)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 Function (java.util.function.Function)3