From a7985c175bd0cee82f1bc7d16b43cbb7ca8b1891 Mon Sep 17 00:00:00 2001 From: Alexander Schwartz Date: Tue, 13 May 2025 16:54:32 +0200 Subject: [PATCH] Reorder operations to avoid the slow operation to get all client sessions Closes #39665 Signed-off-by: Alexander Schwartz --- .../AuthenticationProcessor.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java b/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java index b77ddbe62c7..406d5622af3 100755 --- a/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java +++ b/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java @@ -1162,13 +1162,20 @@ public class AuthenticationProcessor { event.detail(Details.REMEMBER_ME, "true"); } - final int clientSessions = userSession.getAuthenticatedClientSessions().size(); - ClientSessionContext clientSessionCtx = TokenManager.attachAuthenticationSession(session, userSession, authSession); - if (clientSessions == 0 && userSession.getStarted() == userSession.getLastSessionRefresh() - && TokenUtil.hasScope(clientSessionCtx.getScopeString(), OAuth2Constants.OFFLINE_ACCESS)) { - // user session is just created, empty and the first access was for offline token, set the note - clientSessionCtx.getClientSession().setNote(FIRST_OFFLINE_ACCESS, Boolean.TRUE.toString()); + ClientSessionContext clientSessionCtx; + if (userSession.getStarted() == userSession.getLastSessionRefresh()) { + // calling getAuthenticatedClientSessions() will pull all client sessions and is therefore expensive. + // The nested ifs try to avoid the common case when the session already exists for some time and this is then called. + final int clientSessions = userSession.getAuthenticatedClientSessions().size(); + clientSessionCtx = TokenManager.attachAuthenticationSession(session, userSession, authSession); + if (clientSessions == 0 && TokenUtil.hasScope(clientSessionCtx.getScopeString(), OAuth2Constants.OFFLINE_ACCESS)) { + // user session is just created, empty and the first access was for offline token, set the note + clientSessionCtx.getClientSession().setNote(FIRST_OFFLINE_ACCESS, Boolean.TRUE.toString()); + } else { + clientSessionCtx.getClientSession().removeNote(FIRST_OFFLINE_ACCESS); + } } else { + clientSessionCtx = TokenManager.attachAuthenticationSession(session, userSession, authSession); clientSessionCtx.getClientSession().removeNote(FIRST_OFFLINE_ACCESS); }