Map Store Removal: Remove LockObjectsForModification (#25323)

Signed-off-by: vramik <vramik@redhat.com>

Closes #24793
This commit is contained in:
Vlasta Ramik 2023-12-07 07:43:43 -05:00 committed by GitHub
parent 0e535d2bbe
commit df465456b8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 36 additions and 182 deletions

View file

@ -1,104 +0,0 @@
/*
* Copyright 2022 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.utils;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
import java.util.HashSet;
import java.util.Set;
/**
* This flags the session that all information loaded from the stores should be locked as the service layer
* plans to modify it.
*
* This is just a hint to the underlying storage, and a store might choose to ignore it.
* The lock for any object retrieved from the session will be kept until the end of the transaction.
*
* If the store supports it, this could prevent exceptions due to optimistic locking
* problems later in the processing. If the caller retrieved objects without this wrapper, they would still be
* able to modify those objects, and those changes would be written to the store at the end of the transaction at the lastet,
* but they won't be locked.
*
*
* @author Alexander Schwartz
*/
public class LockObjectsForModification {
private static final String ATTRIBUTE = LockObjectsForModification.class.getCanonicalName();
public static boolean isEnabled(KeycloakSession session, Class<?> model) {
Set<Class<?>> lockedModels = getAttribute(session);
return lockedModels != null && lockedModels.contains(model);
}
private static Set<Class<?>> getAttribute(KeycloakSession session) {
//noinspection unchecked
return (Set<Class<?>>) session.getAttribute(ATTRIBUTE);
}
private static Set<Class<?>> getOrCreateAttribute(KeycloakSession session) {
Set<Class<?>> attribute = getAttribute(session);
if (attribute == null) {
attribute = new HashSet<>();
session.setAttribute(ATTRIBUTE, attribute);
}
return attribute;
}
public static <V> V lockUserSessionsForModification(KeycloakSession session, CallableWithoutThrowingAnException<V> callable) {
return lockObjectsForModification(session, UserSessionModel.class, callable);
}
public static <V> V lockRealmsForModification(KeycloakSession session, CallableWithoutThrowingAnException<V> callable) {
return lockObjectsForModification(session, RealmModel.class, callable);
}
private static <V> V lockObjectsForModification(KeycloakSession session, Class<?> model, CallableWithoutThrowingAnException<V> callable) {
// Only map storage supported locking objects for modification, this logic will be remove in a follow up PR
return callable.call();
}
@FunctionalInterface
public interface CallableWithoutThrowingAnException<V> {
/**
* Computes a result.
*
* @return computed result
*/
V call();
}
public static class Enabled implements AutoCloseable {
private final KeycloakSession session;
private final Class<?> model;
public Enabled(KeycloakSession session, Class<?> model) {
this.session = session;
this.model = model;
getOrCreateAttribute(session).add(model);
}
@Override
public void close() {
getOrCreateAttribute(session).remove(model);
}
}
}

View file

@ -71,7 +71,6 @@ import java.util.Map;
import java.util.Set;
import static org.keycloak.models.light.LightweightUserAdapter.isLightweightUser;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -1064,7 +1063,7 @@ public class AuthenticationProcessor {
if (userSession == null) { // if no authenticator attached a usersession
userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, authSession.getParentSession().getId()));
userSession = session.sessions().getUserSession(realm, authSession.getParentSession().getId());
if (userSession == null) {
UserSessionModel.SessionPersistenceState persistenceState = UserSessionModel.SessionPersistenceState.fromString(authSession.getClientNote(AuthenticationManager.USER_SESSION_PERSISTENT_STATE));

View file

@ -25,8 +25,6 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.utils.StringUtil;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
public class UserSessionLimitsAuthenticator implements Authenticator {
private static Logger logger = Logger.getLogger(UserSessionLimitsAuthenticator.class);
@ -58,7 +56,7 @@ public class UserSessionLimitsAuthenticator implements Authenticator {
if (context.getRealm() != null && context.getUser() != null) {
// Get the session count in this realm for this specific user
List<UserSessionModel> userSessionsForRealm = lockUserSessionsForModification(session, () -> session.sessions().getUserSessionsStream(context.getRealm(), context.getUser()).collect(Collectors.toList()));
List<UserSessionModel> userSessionsForRealm = session.sessions().getUserSessionsStream(context.getRealm(), context.getUser()).collect(Collectors.toList());
int userSessionCountForRealm = userSessionsForRealm.size();
// Get the session count related to the current client for this user

View file

@ -100,8 +100,6 @@ import org.keycloak.sessions.RootAuthenticationSessionModel;
import org.keycloak.util.JsonSerialization;
import org.keycloak.services.util.DefaultClientSessionContext;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
@ -318,7 +316,7 @@ public class AuthorizationTokenService {
userSessionModel = new UserSessionManager(keycloakSession).createUserSession(KeycloakModelUtils.generateId(), realm, user, user.getUsername(), request.getClientConnection().getRemoteAddr(),
ServiceAccountConstants.CLIENT_AUTH, false, null, null, UserSessionModel.SessionPersistenceState.TRANSIENT);
} else {
userSessionModel = lockUserSessionsForModification(keycloakSession, () -> sessions.getUserSession(realm, accessToken.getSessionState()));
userSessionModel = sessions.getUserSession(realm, accessToken.getSessionState());
if (userSessionModel == null) {
userSessionModel = sessions.getOfflineUserSession(realm, accessToken.getSessionState());

View file

@ -46,8 +46,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
@ -128,7 +126,7 @@ public class KeycloakIdentity implements Identity {
this.accessToken = AccessToken.class.cast(token);
} else {
UserSessionProvider sessions = keycloakSession.sessions();
UserSessionModel userSession = lockUserSessionsForModification(keycloakSession, () -> sessions.getUserSession(realm, token.getSessionState()));
UserSessionModel userSession = sessions.getUserSession(realm, token.getSessionState());
if (userSession == null) {
userSession = sessions.getOfflineUserSession(realm, token.getSessionState());
@ -297,7 +295,7 @@ public class KeycloakIdentity implements Identity {
}
UserSessionProvider sessions = keycloakSession.sessions();
UserSessionModel userSession = lockUserSessionsForModification(keycloakSession, () -> sessions.getUserSession(realm, accessToken.getSessionState()));
UserSessionModel userSession = sessions.getUserSession(realm, accessToken.getSessionState());
if (userSession == null) {
userSession = sessions.getOfflineUserSession(realm, accessToken.getSessionState());

View file

@ -43,8 +43,6 @@ import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response;
import java.io.IOException;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@ -97,7 +95,7 @@ public class KeycloakOIDCIdentityProvider extends OIDCIdentityProvider {
if (action.getKeycloakSessionIds() != null) {
for (String sessionId : action.getKeycloakSessionIds()) {
String brokerSessionId = provider.getConfig().getAlias() + "." + sessionId;
UserSessionModel userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSessionByBrokerSessionId(realm, brokerSessionId));
UserSessionModel userSession = session.sessions().getUserSessionByBrokerSessionId(realm, brokerSessionId);
if (userSession != null
&& userSession.getState() != UserSessionModel.State.LOGGING_OUT
&& userSession.getState() != UserSessionModel.State.LOGGED_OUT

View file

@ -82,8 +82,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* @author Pedro Igor
*/
@ -333,7 +331,7 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
return ErrorPage.error(session, null, Response.Status.BAD_REQUEST, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
}
UserSessionModel userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, state));
UserSessionModel userSession = session.sessions().getUserSession(realm, state);
if (userSession == null) {
logger.error("no valid user session");
EventBuilder event = new EventBuilder(realm, session, clientConnection);

View file

@ -129,8 +129,6 @@ import java.util.Collections;
import jakarta.ws.rs.core.MultivaluedMap;
import javax.xml.crypto.dsig.XMLSignature;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@ -349,7 +347,7 @@ public class SAMLEndpoint {
} else {
for (String sessionIndex : request.getSessionIndex()) {
String brokerSessionId = config.getAlias() + "." + sessionIndex;
UserSessionModel userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSessionByBrokerSessionId(realm, brokerSessionId));
UserSessionModel userSession = session.sessions().getUserSessionByBrokerSessionId(realm, brokerSessionId);
if (userSession != null) {
if (userSession.getState() == UserSessionModel.State.LOGGING_OUT || userSession.getState() == UserSessionModel.State.LOGGED_OUT) {
continue;
@ -724,7 +722,7 @@ public class SAMLEndpoint {
event.error(Errors.USER_SESSION_NOT_FOUND);
return ErrorPage.error(session, null, Response.Status.BAD_REQUEST, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
}
UserSessionModel userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, relayState));
UserSessionModel userSession = session.sessions().getUserSession(realm, relayState);
if (userSession == null) {
logger.error("no valid user session");
event.event(EventType.LOGOUT);

View file

@ -116,7 +116,6 @@ import jakarta.ws.rs.core.UriInfo;
import static org.keycloak.models.light.LightweightUserAdapter.isLightweightUser;
import static org.keycloak.representations.IDToken.NONCE;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* Stateless object that creates tokens and manages oauth access codes
@ -164,7 +163,7 @@ public class TokenManager {
}
} else {
// Find userSession regularly for online tokens
userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, oldToken.getSessionState()));
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");
@ -325,10 +324,10 @@ public class TokenManager {
private boolean validateTokenReuseForIntrospection(KeycloakSession session, RealmModel realm, AccessToken token) {
UserSessionModel userSession = null;
if (token.getType().equals(TokenUtil.TOKEN_TYPE_REFRESH)) {
userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, token.getSessionState()));
userSession = session.sessions().getUserSession(realm, token.getSessionState());
} else {
UserSessionManager sessionManager = new UserSessionManager(session);
userSession = lockUserSessionsForModification(session, () -> sessionManager.findOfflineUserSession(realm, token.getSessionState()));
userSession = sessionManager.findOfflineUserSession(realm, token.getSessionState());
}
ClientModel client = realm.getClientByClientId(token.getIssuedFor());

View file

@ -20,7 +20,6 @@ package org.keycloak.protocol.oidc.endpoints;
import static org.keycloak.models.UserSessionModel.State.LOGGED_OUT;
import static org.keycloak.models.UserSessionModel.State.LOGGING_OUT;
import static org.keycloak.services.resources.LoginActionsService.SESSION_CODE;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache;
@ -435,7 +434,7 @@ public class LogoutEndpoint {
String idTokenIssuedAtStr = logoutSession.getAuthNote(OIDCLoginProtocol.LOGOUT_VALIDATED_ID_TOKEN_ISSUED_AT);
if (userSessionIdFromIdToken != null && idTokenIssuedAtStr != null) {
try {
userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, userSessionIdFromIdToken));
userSession = session.sessions().getUserSession(realm, userSessionIdFromIdToken);
if (userSession == null) {
event.event(EventType.LOGOUT);
@ -452,8 +451,7 @@ public class LogoutEndpoint {
}
// authenticate identity cookie, but ignore an access token timeout as we're logging out anyways.
AuthenticationManager.AuthResult authResult = lockUserSessionsForModification(session,
() -> AuthenticationManager.authenticateIdentityCookie(session, realm, false));
AuthenticationManager.AuthResult authResult = AuthenticationManager.authenticateIdentityCookie(session, realm, false);
if (authResult != null) {
userSession = userSession != null ? userSession : authResult.getSession();
return initiateBrowserLogout(userSession);
@ -533,7 +531,7 @@ public class LogoutEndpoint {
userSessionModel = sessionManager.findOfflineUserSession(realm, token.getSessionState());
} else {
String sessionState = token.getSessionState();
userSessionModel = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, sessionState));
userSessionModel = session.sessions().getUserSession(realm, sessionState);
}
if (userSessionModel != null) {
@ -633,8 +631,7 @@ public class LogoutEndpoint {
AtomicReference<BackchannelLogoutResponse> backchannelLogoutResponse = new AtomicReference<>(new BackchannelLogoutResponse());
backchannelLogoutResponse.get().setLocalLogoutSucceeded(true);
identityProviderAliases.forEach(identityProviderAlias -> {
UserSessionModel userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSessionByBrokerSessionId(realm,
identityProviderAlias + "." + sessionId));
UserSessionModel userSession = session.sessions().getUserSessionByBrokerSessionId(realm, identityProviderAlias + "." + sessionId);
if (logoutOfflineSessions) {
if (offlineSessionsLazyLoadingEnabled) {

View file

@ -124,8 +124,6 @@ import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
@ -574,7 +572,7 @@ public class TokenEndpoint {
res = responseBuilder.build();
if (!responseBuilder.isOfflineToken()) {
UserSessionModel userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, res.getSessionState()));
UserSessionModel userSession = session.sessions().getUserSession(realm, res.getSessionState());
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId());
updateClientSession(clientSession);
updateUserSessionFromClientAuth(userSession);

View file

@ -18,7 +18,6 @@
package org.keycloak.protocol.oidc.grants.device;
import static org.keycloak.protocol.oidc.OIDCLoginProtocolService.tokenServiceBaseUrl;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
import org.keycloak.OAuth2Constants;
import org.keycloak.OAuthErrorException;
@ -291,7 +290,7 @@ public class DeviceGrantType {
client.getId());
if (userSession == null) {
userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, userSessionId));
userSession = session.sessions().getUserSession(realm, userSessionId);
if (userSession == null) {
throw new CorsErrorResponseException(cors, OAuthErrorException.AUTHORIZATION_PENDING,
"The authorization request is verified but can not lookup the user session yet",

View file

@ -31,8 +31,6 @@ import org.keycloak.models.SingleUseObjectProvider;
import org.keycloak.models.UserSessionModel;
import org.keycloak.services.managers.UserSessionCrossDCManager;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@ -101,10 +99,10 @@ public class OAuth2CodeParser {
}
// Retrieve UserSession
UserSessionModel userSession = lockUserSessionsForModification(session, () -> new UserSessionCrossDCManager(session).getUserSessionWithClient(realm, userSessionId, clientUUID));
UserSessionModel userSession = new UserSessionCrossDCManager(session).getUserSessionWithClient(realm, userSessionId, clientUUID);
if (userSession == null) {
// Needed to track if code is invalid or was already used.
userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, userSessionId));
userSession = session.sessions().getUserSession(realm, userSessionId);
if (userSession == null) {
return result.illegalCode();
}

View file

@ -144,8 +144,6 @@ import jakarta.ws.rs.core.MultivaluedMap;
import javax.xml.parsers.ParserConfigurationException;
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* Resource class for the saml connect token service
@ -1164,7 +1162,7 @@ public class SamlService extends AuthorizationEndpointBase {
return emptyArtifactResponseMessage(artifactResolveMessage, null);
}
UserSessionModel userSessionModel = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, sessionMapping.get(SamlProtocol.USER_SESSION_ID)));
UserSessionModel userSessionModel = session.sessions().getUserSession(realm, sessionMapping.get(SamlProtocol.USER_SESSION_ID));
if (userSessionModel == null) {
logger.errorf("UserSession with id: %s, that corresponds to artifact: %s does not exist.", sessionMapping.get(SamlProtocol.USER_SESSION_ID), artifact);
return emptyArtifactResponseMessage(artifactResolveMessage, null);

View file

@ -115,7 +115,6 @@ import static org.keycloak.models.light.LightweightUserAdapter.isLightweightUser
import static org.keycloak.models.UserSessionModel.CORRESPONDING_SESSION_ID;
import static org.keycloak.protocol.oidc.grants.device.DeviceGrantType.isOAuth2DeviceVerificationFlow;
import static org.keycloak.services.util.CookieHelper.getCookie;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* Stateless object that manages authentication
@ -229,7 +228,7 @@ public class AuthenticationManager {
verifier.verifierContext(signatureVerifier);
AccessToken token = verifier.verify().getToken();
UserSessionModel cookieSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, token.getSessionState()));
UserSessionModel cookieSession = session.sessions().getUserSession(realm, token.getSessionState());
if (cookieSession == null || !cookieSession.getId().equals(userSession.getId())) return true;
expireIdentityCookie(realm, uriInfo, session);
return true;
@ -319,9 +318,9 @@ public class AuthenticationManager {
// Check if "online" session still exists and remove it too
String onlineUserSessionId = userSession.getNote(CORRESPONDING_SESSION_ID);
UserSessionModel onlineUserSession = lockUserSessionsForModification(session, () -> (onlineUserSessionId != null) ?
UserSessionModel onlineUserSession = onlineUserSessionId != null ?
session.sessions().getUserSession(realm, onlineUserSessionId) :
session.sessions().getUserSession(realm, userSession.getId()));
session.sessions().getUserSession(realm, userSession.getId());
if (onlineUserSession != null) {
session.sessions().removeUserSession(realm, onlineUserSession);
@ -950,7 +949,7 @@ public class AuthenticationManager {
if (split.length >= 3) {
String oldSessionId = split[2];
if (!oldSessionId.equals(userSession.getId())) {
UserSessionModel oldSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, oldSessionId));
UserSessionModel oldSession = session.sessions().getUserSession(realm, oldSessionId);
if (oldSession != null) {
logger.debugv("Removing old user session: session: {0}", oldSessionId);
session.sessions().removeUserSession(realm, oldSession);

View file

@ -28,23 +28,18 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.models.utils.SessionExpiration;
import org.keycloak.protocol.RestartLoginCookie;
import org.keycloak.services.resources.LoginActionsService;
import org.keycloak.services.util.CookieHelper;
import org.keycloak.sessions.AuthenticationSessionModel;
import org.keycloak.sessions.CommonClientSessionModel;
import org.keycloak.sessions.RootAuthenticationSessionModel;
import org.keycloak.sessions.StickySessionEncoderProvider;
import jakarta.ws.rs.core.UriInfo;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static org.keycloak.authentication.AuthenticationProcessor.CURRENT_FLOW_PATH;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -108,7 +103,7 @@ public class AuthenticationSessionManager {
AuthSessionId authSessionId = decodeAuthSessionId(oldEncodedId);
String sessionId = authSessionId.getDecodedId();
UserSessionModel userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, sessionId));
UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
if (userSession != null) {
reencodeAuthSessionCookie(oldEncodedId, authSessionId, realm);
@ -284,7 +279,7 @@ public class AuthenticationSessionManager {
// Check to see if we already have authenticationSession with same ID
public UserSessionModel getUserSession(AuthenticationSessionModel authSession) {
return lockUserSessionsForModification(session, () -> session.sessions().getUserSession(authSession.getRealm(), authSession.getParentSession().getId()));
return session.sessions().getUserSession(authSession.getRealm(), authSession.getParentSession().getId());
}

View file

@ -28,7 +28,6 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
import static org.keycloak.services.managers.AuthenticationManager.authenticateIdentityCookie;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -72,7 +71,7 @@ public class UserSessionCrossDCManager {
// in case the auth session was removed, we fall back to the identity cookie
// we are here doing the user session lookup twice, however the second lookup is going to make sure the
// session exists in remote caches
AuthenticationManager.AuthResult authResult = lockUserSessionsForModification(kcSession, () -> authenticateIdentityCookie(kcSession, realm, true));
AuthenticationManager.AuthResult authResult = authenticateIdentityCookie(kcSession, realm, true);
if (authResult != null && authResult.getSession() != null) {
sessionCookies = Collections.singletonList(authResult.getSession().getId());
@ -84,9 +83,9 @@ public class UserSessionCrossDCManager {
String sessionId = authSessionId.getDecodedId();
// This will remove userSession "locally" if it doesn't exist on remoteCache
lockUserSessionsForModification(kcSession, () -> kcSession.sessions().getUserSessionWithPredicate(realm, sessionId, false, (UserSessionModel userSession2) -> userSession2 == null));
kcSession.sessions().getUserSessionWithPredicate(realm, sessionId, false, (UserSessionModel userSession2) -> userSession2 == null);
UserSessionModel userSession = lockUserSessionsForModification(kcSession, () -> kcSession.sessions().getUserSession(realm, sessionId));
UserSessionModel userSession = kcSession.sessions().getUserSession(realm, sessionId);
if (userSession != null) {
asm.reencodeAuthSessionCookie(oldEncodedId, authSessionId, realm);

View file

@ -43,8 +43,6 @@ import java.util.Objects;
import java.util.function.Consumer;
import org.jboss.logging.Logger;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
*
* @author hmlnarik
@ -123,7 +121,7 @@ public class LoginActionsServiceChecks {
return;
}
UserSessionModel userSession = lockUserSessionsForModification(context.getSession(), () -> context.getSession().sessions().getUserSession(context.getRealm(), authSessionId));
UserSessionModel userSession = context.getSession().sessions().getUserSession(context.getRealm(), authSessionId);
boolean hasNoRequiredActions =
(userSession == null || userSession.getUser().getRequiredActionsStream().count() == 0)
&&

View file

@ -18,7 +18,6 @@
package org.keycloak.services.resources;
import static org.keycloak.services.managers.AuthenticationManager.authenticateIdentityCookie;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
import java.net.URI;
@ -40,7 +39,6 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.AuthorizationEndpointBase;
import org.keycloak.protocol.RestartLoginCookie;
import org.keycloak.services.ErrorPage;
@ -185,7 +183,7 @@ public class SessionCodeChecks {
// if restart from cookie was not found check if the user is already authenticated
if (response.getStatus() != Response.Status.FOUND.getStatusCode()) {
AuthenticationManager.AuthResult authResult = lockUserSessionsForModification(session, () -> authenticateIdentityCookie(session, realm, false));
AuthenticationManager.AuthResult authResult = authenticateIdentityCookie(session, realm, false);
if (authResult != null && authResult.getSession() != null) {
LoginFormsProvider loginForm = session.getProvider(LoginFormsProvider.class).setAuthenticationSession(authSession)

View file

@ -32,7 +32,6 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.keycloak.common.util.Time;
import org.keycloak.device.DeviceActivityManager;
import org.keycloak.models.AccountRoles;
import org.keycloak.models.ClientModel;
@ -46,8 +45,6 @@ import org.keycloak.representations.account.SessionRepresentation;
import org.keycloak.services.managers.Auth;
import org.keycloak.services.managers.AuthenticationManager;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
@ -147,7 +144,7 @@ public class SessionResource {
@NoCache
public Response logout(@PathParam("id") String id) {
auth.require(AccountRoles.MANAGE_ACCOUNT);
UserSessionModel userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, id));
UserSessionModel userSession = session.sessions().getUserSession(realm, id);
if (userSession != null && userSession.getUser().equals(user)) {
AuthenticationManager.backchannelLogout(session, userSession, true);
}

View file

@ -16,7 +16,6 @@
*/
package org.keycloak.services.resources.admin;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
import static org.keycloak.util.JsonSerialization.readValue;
import java.io.InputStream;
@ -633,7 +632,7 @@ public class RealmAdminResource {
public void deleteSession(@PathParam("session") String sessionId) {
auth.users().requireManage();
UserSessionModel userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, sessionId));
UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
if (userSession == null) throw new NotFoundException("Sesssion not found");
AuthenticationManager.backchannelLogout(session, realm, userSession, session.getContext().getUri(), connection, headers, true);
adminEvent.operation(OperationType.DELETE).resource(ResourceType.USER_SESSION).resourcePath(session.getContext().getUri()).success();

View file

@ -125,7 +125,6 @@ import static org.keycloak.models.ImpersonationSessionNote.IMPERSONATOR_ID;
import static org.keycloak.models.ImpersonationSessionNote.IMPERSONATOR_USERNAME;
import static org.keycloak.services.resources.admin.UserProfileResource.createUserProfileMetadata;
import static org.keycloak.userprofile.UserProfileContext.USER_API;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
/**
* Base resource for managing users
@ -359,7 +358,7 @@ public class UserResource {
String sessionState = auth.adminAuth().getToken().getSessionState();
if (authenticatedRealm.getId().equals(realm.getId()) && sessionState != null) {
sameRealm = true;
UserSessionModel userSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(authenticatedRealm, sessionState));
UserSessionModel userSession = session.sessions().getUserSession(authenticatedRealm, sessionState);
AuthenticationManager.expireIdentityCookie(realm, session.getContext().getUri(), session);
AuthenticationManager.expireRememberMeCookie(realm, session.getContext().getUri(), session);
AuthenticationManager.expireAuthSessionCookie(realm, session.getContext().getUri(), session);

View file

@ -37,8 +37,6 @@ import java.util.stream.IntStream;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.aMapWithSize;
import static org.hamcrest.Matchers.startsWith;
import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification;
@RequireProvider(UserSessionProvider.class)
public class UserSessionConcurrencyTest extends KeycloakModelTest {
@ -87,7 +85,7 @@ public class UserSessionConcurrencyTest extends KeycloakModelTest {
RealmModel realm = session.realms().getRealm(realmId);
ClientModel client = realm.getClientByClientId("client" + (n % CLIENTS_COUNT));
UserSessionModel uSession = lockUserSessionsForModification(session, () -> session.sessions().getUserSession(realm, uId));
UserSessionModel uSession = session.sessions().getUserSession(realm, uId);
AuthenticatedClientSessionModel cSession = uSession.getAuthenticatedClientSessionByClient(client.getId());
if (cSession == null) {
wasWriting.set(true);