Merge pull request #4610 from hmlnarik/KEYCLOAK-5745-Extract-client-sessions-from-user-sessions

KEYCLOAK-5745 Separate user and client sessions in infinispan
This commit is contained in:
Hynek Mlnařík authored and GitHub committed 2017-10-26 13:09:06 +02:00
commit 248da4687a
61 files changed
+919 -443

No files matched your search

@@ -159,13 +159,13 @@ public class TokenManager {
}
ClientModel client = session.getContext().getClient();
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessions().get(client.getId());
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId());
// Can theoretically happen in cross-dc environment. Try to see if userSession with our client is available in remoteCache
if (clientSession == null) {
userSession = new UserSessionCrossDCManager(session).getUserSessionWithClient(realm, userSession.getId(), offline, client.getId());
if (userSession != null) {
clientSession = userSession.getAuthenticatedClientSessions().get(client.getId());
clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId());
} else {
throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Session doesn't have required client", "Session doesn't have required client");
}
@@ -400,7 +400,7 @@ public class TokenManager {
public static AuthenticatedClientSessionModel attachAuthenticationSession(KeycloakSession session, UserSessionModel userSession, AuthenticationSessionModel authSession) {
ClientModel client = authSession.getClient();
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessions().get(client.getId());
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId());
if (clientSession == null) {
clientSession = session.sessions().createClientSession(userSession.getRealm(), client, userSession);
}
@@ -436,8 +436,9 @@ public class TokenManager {
return;
}
clientSession.setUserSession(null);
clientSession.detachFromUserSession();
// TODO: Might need optimization to prevent loading client sessions from cache in getAuthenticatedClientSessions()
if (userSession.getAuthenticatedClientSessions().isEmpty()) {
sessions.removeUserSession(realm, userSession);
}
@@ -254,7 +254,7 @@ public class TokenEndpoint {
// Attempt to use same code twice should invalidate existing clientSession
if (clientSession != null) {
clientSession.setUserSession(null);
clientSession.detachFromUserSession();
}
event.error(Errors.INVALID_CODE);
@@ -400,7 +400,7 @@ public class TokenEndpoint {
if (!result.isOfflineToken()) {
UserSessionModel userSession = session.sessions().getUserSession(realm, res.getSessionState());
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessions().get(client.getId());
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId());
updateClientSession(clientSession);
updateUserSessionFromClientAuth(userSession);
}
@@ -166,7 +166,7 @@ public class UserInfoEndpoint {
// Existence of authenticatedClientSession for our client already handled before
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessions().get(clientModel.getId());
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(clientModel.getId());
AccessToken userInfo = new AccessToken();
tokenManager.transformUserInfoAccessToken(session, userInfo, realm, clientModel, userModel, userSession, clientSession);
@@ -400,7 +400,7 @@ public class SamlService extends AuthorizationEndpointBase {
userSession.setNote(SamlProtocol.SAML_LOGOUT_CANONICALIZATION, samlClient.getCanonicalizationMethod());
userSession.setNote(AuthenticationManager.KEYCLOAK_LOGOUT_PROTOCOL, SamlProtocol.LOGIN_PROTOCOL);
// remove client from logout requests
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessions().get(client.getId());
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId());
if (clientSession != null) {
clientSession.setAction(AuthenticationSessionModel.Action.LOGGED_OUT.name());
}
@@ -62,7 +62,7 @@ public class SamlSessionUtils {
return null;
}
return userSession.getAuthenticatedClientSessions().get(parts[1]);
return userSession.getAuthenticatedClientSessionByClient(clientUUID);
}
}
@@ -395,7 +395,7 @@ public class AuthenticationManager {
public static void backchannelLogoutUserFromClient(KeycloakSession session, RealmModel realm, UserModel user, ClientModel client, UriInfo uriInfo, HttpHeaders headers) {
List<UserSessionModel> userSessions = session.sessions().getUserSessions(realm, user);
for (UserSessionModel userSession : userSessions) {
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessions().get(client.getId());
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId());
if (clientSession != null) {
AuthenticationManager.backchannelLogoutClientSession(session, realm, clientSession, null, uriInfo, headers);
clientSession.setAction(AuthenticationSessionModel.Action.LOGGED_OUT.name());
@@ -172,7 +172,7 @@ class CodeGenerateUtil {
}
}
return userSession.getAuthenticatedClientSessions().get(codeJWT.getIssuedFor());
return userSession.getAuthenticatedClientSessionByClient(codeJWT.getIssuedFor());
}
@@ -42,7 +42,7 @@ public class UserSessionCrossDCManager {
// get userSession if it has "authenticatedClientSession" of specified client attached to it. Otherwise download it from remoteCache
public UserSessionModel getUserSessionWithClient(RealmModel realm, String id, boolean offline, String clientUUID) {
return kcSession.sessions().getUserSessionWithPredicate(realm, id, offline, userSession -> userSession.getAuthenticatedClientSessions().containsKey(clientUUID));
return kcSession.sessions().getUserSessionWithPredicate(realm, id, offline, userSession -> userSession.getAuthenticatedClientSessionByClient(clientUUID) != null);
}
@@ -52,8 +52,8 @@ public class UserSessionCrossDCManager {
return kcSession.sessions().getUserSessionWithPredicate(realm, id, false, (UserSessionModel userSession) -> {
Map<String, AuthenticatedClientSessionModel> authSessions = userSession.getAuthenticatedClientSessions();
return authSessions.containsKey(clientUUID);
AuthenticatedClientSessionModel authSessions = userSession.getAuthenticatedClientSessionByClient(clientUUID);
return authSessions != null;
});
}
@@ -63,7 +63,7 @@ public class UserSessionManager {
}
// Create and persist clientSession
AuthenticatedClientSessionModel offlineClientSession = offlineUserSession.getAuthenticatedClientSessions().get(clientSession.getClient().getId());
AuthenticatedClientSessionModel offlineClientSession = offlineUserSession.getAuthenticatedClientSessionByClient(clientSession.getClient().getId());
if (offlineClientSession == null) {
createOfflineClientSession(user, clientSession, offlineUserSession);
}
@@ -97,14 +97,14 @@ public class UserSessionManager {
List<UserSessionModel> userSessions = kcSession.sessions().getOfflineUserSessions(realm, user);
boolean anyRemoved = false;
for (UserSessionModel userSession : userSessions) {
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessions().get(client.getId());
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId());
if (clientSession != null) {
if (logger.isTraceEnabled()) {
logger.tracef("Removing existing offline token for user '%s' and client '%s' .",
user.getUsername(), client.getClientId());
}
clientSession.setUserSession(null);
clientSession.detachFromUserSession();
persister.removeClientSession(userSession.getId(), client.getId(), true);
checkOfflineUserSessionHasClientSessions(realm, user, userSession);
anyRemoved = true;
@@ -154,7 +154,8 @@ public class UserSessionManager {
// Check if userSession has any offline clientSessions attached to it. Remove userSession if not
private void checkOfflineUserSessionHasClientSessions(RealmModel realm, UserModel user, UserSessionModel userSession) {
if (userSession.getAuthenticatedClientSessions().size() > 0) {
// TODO: Might need optimization to prevent loading client sessions from cache
if (! userSession.getAuthenticatedClientSessions().isEmpty()) {
return;
}
@@ -142,7 +142,7 @@ public class AccountFormService extends AbstractSecuredLocalService {
if (authResult != null) {
UserSessionModel userSession = authResult.getSession();
if (userSession != null) {
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessions().get(client.getId());
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId());
if (clientSession == null) {
clientSession = session.sessions().createClientSession(userSession.getRealm(), client, userSession);
}
@@ -339,7 +339,7 @@ public class UserResource {
UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(session);
// Update lastSessionRefresh with the timestamp from clientSession
AuthenticatedClientSessionModel clientSession = session.getAuthenticatedClientSessions().get(clientId);
AuthenticatedClientSessionModel clientSession = session.getAuthenticatedClientSessionByClient(clientId);
// Skip if userSession is not for this client
if (clientSession == null) {