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);
}
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");
}
}
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");
}
}
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");
}
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);
}
}
Aggregations