diff --git a/services/src/main/java/org/keycloak/locale/DefaultLocaleSelectorProvider.java b/services/src/main/java/org/keycloak/locale/DefaultLocaleSelectorProvider.java index 6b377b27dc..2faf7b80b7 100644 --- a/services/src/main/java/org/keycloak/locale/DefaultLocaleSelectorProvider.java +++ b/services/src/main/java/org/keycloak/locale/DefaultLocaleSelectorProvider.java @@ -118,7 +118,7 @@ public class DefaultLocaleSelectorProvider implements LocaleSelectorProvider { return null; } - String locale = session.getAuthNote(LocaleSelectorProvider.CLIENT_REQUEST_LOCALE); + String locale = session.getClientNote(LocaleSelectorProvider.CLIENT_REQUEST_LOCALE); if (locale == null) { return null; } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java index 033d0bbd79..f6c38c934b 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java @@ -313,7 +313,7 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase { performActionOnParameters(request, (paramName, paramValue) -> {if (paramValue != null) authenticationSession.setClientNote(paramName, paramValue);}); if (request.getMaxAge() != null) authenticationSession.setClientNote(OIDCLoginProtocol.MAX_AGE_PARAM, String.valueOf(request.getMaxAge())); - if (request.getUiLocales() != null) authenticationSession.setAuthNote(LocaleSelectorProvider.CLIENT_REQUEST_LOCALE, request.getUiLocales()); + if (request.getUiLocales() != null) authenticationSession.setClientNote(LocaleSelectorProvider.CLIENT_REQUEST_LOCALE, request.getUiLocales()); Map acrLoaMap = AcrUtils.getAcrLoaMap(authenticationSession.getClient()); List acrValues = AcrUtils.getRequiredAcrValues(request.getClaims()); diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java index 745e79c23a..766f81790f 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java @@ -256,7 +256,7 @@ public class LogoutEndpoint { AuthenticationSessionModel logoutSession = AuthenticationManager.createOrJoinLogoutSession(session, realm, new AuthenticationSessionManager(session), null, true); session.getContext().setAuthenticationSession(logoutSession); if (uiLocales != null) { - logoutSession.setAuthNote(LocaleSelectorProvider.CLIENT_REQUEST_LOCALE, uiLocales); + logoutSession.setClientNote(LocaleSelectorProvider.CLIENT_REQUEST_LOCALE, uiLocales); } if (validatedRedirectUri != null) { logoutSession.setAuthNote(OIDCLoginProtocol.LOGOUT_REDIRECT_URI, validatedRedirectUri); diff --git a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java index 24bcdad71c..6766a33e5f 100755 --- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java +++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java @@ -580,10 +580,12 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal boolean forwardedPassiveLogin = "true".equals(authenticationSession.getAuthNote(AuthenticationProcessor.FORWARDED_PASSIVE_LOGIN)); - Map extractedAuthNotes = extractAuthNotesFromSession(authenticationSession); + String userRequestedLocale = authenticationSession.getAuthNote(LocaleSelectorProvider.USER_REQUEST_LOCALE); // Redirect to firstBrokerLogin after successful login and ensure that previous authentication state removed AuthenticationProcessor.resetFlow(authenticationSession, LoginActionsService.FIRST_BROKER_LOGIN_PATH); - extractedAuthNotes.forEach(authenticationSession::setAuthNote); + if (userRequestedLocale != null) { + authenticationSession.setAuthNote(LocaleSelectorProvider.USER_REQUEST_LOCALE, userRequestedLocale); + } // Set the FORWARDED_PASSIVE_LOGIN note (if needed) after resetting the session so it is not lost. if (forwardedPassiveLogin) { @@ -616,18 +618,6 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal } } - private Map extractAuthNotesFromSession(AuthenticationSessionModel authenticationSession) { - return Stream.of( - LocaleSelectorProvider.USER_REQUEST_LOCALE, - LocaleSelectorProvider.CLIENT_REQUEST_LOCALE - ) - .filter(it -> authenticationSession.getAuthNote(it) != null) - .collect(Collectors.toMap( - Function.identity(), - authenticationSession::getAuthNote - )); - } - public Response validateUser(AuthenticationSessionModel authSession, UserModel user, RealmModel realm) { if (!user.isEnabled()) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/EmailTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/EmailTest.java index e5170892cb..93c2f3f3f7 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/EmailTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/i18n/EmailTest.java @@ -45,6 +45,7 @@ import org.keycloak.testsuite.util.DroneUtils; import org.keycloak.testsuite.util.GreenMailRule; import org.keycloak.testsuite.util.MailUtils; import org.keycloak.testsuite.util.WaitUtils; +import org.openqa.selenium.By; /** * @author Michael Gerber @@ -190,4 +191,25 @@ public class EmailTest extends AbstractI18NTest { assertThat(infoPage.getInfo(), containsString("Your account has been updated.")); } + + // Issue 10981 + @Test + public void resetPasswordOriginalUiLocalePreservedAfterForgetPassword() throws MessagingException, IOException { + oauth.uiLocales("de"); + + // Assert login page is in german + loginPage.open(); + assertEquals("Deutsch", loginPage.getLanguageDropdownText()); + + // Click "Forget password" + driver.findElement(By.linkText("Passwort vergessen?")).click(); + assertEquals("Deutsch", resetPasswordPage.getLanguageDropdownText()); + resetPasswordPage.changePassword("login-test"); + + // Ensure that page is still in german (after authenticationSession was forked on server). The emailSentMessage should be also displayed in german + loginPage.assertCurrent(); + assertEquals("Deutsch", loginPage.getLanguageDropdownText()); + assertEquals("Sie sollten in Kürze eine E-Mail mit weiteren Instruktionen erhalten.", loginPage.getSuccessMessage()); + } + }