Keycloak forgets ui_locales parameter when using reset password

closes #10981
This commit is contained in:
mposolda 2023-07-17 16:56:06 +02:00 committed by Marek Posolda
parent 67b20dfd9b
commit 03716ed452
5 changed files with 29 additions and 17 deletions

View file

@ -118,7 +118,7 @@ public class DefaultLocaleSelectorProvider implements LocaleSelectorProvider {
return null; return null;
} }
String locale = session.getAuthNote(LocaleSelectorProvider.CLIENT_REQUEST_LOCALE); String locale = session.getClientNote(LocaleSelectorProvider.CLIENT_REQUEST_LOCALE);
if (locale == null) { if (locale == null) {
return null; return null;
} }

View file

@ -313,7 +313,7 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase {
performActionOnParameters(request, (paramName, paramValue) -> {if (paramValue != null) authenticationSession.setClientNote(paramName, paramValue);}); 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.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<String, Integer> acrLoaMap = AcrUtils.getAcrLoaMap(authenticationSession.getClient()); Map<String, Integer> acrLoaMap = AcrUtils.getAcrLoaMap(authenticationSession.getClient());
List<String> acrValues = AcrUtils.getRequiredAcrValues(request.getClaims()); List<String> acrValues = AcrUtils.getRequiredAcrValues(request.getClaims());

View file

@ -256,7 +256,7 @@ public class LogoutEndpoint {
AuthenticationSessionModel logoutSession = AuthenticationManager.createOrJoinLogoutSession(session, realm, new AuthenticationSessionManager(session), null, true); AuthenticationSessionModel logoutSession = AuthenticationManager.createOrJoinLogoutSession(session, realm, new AuthenticationSessionManager(session), null, true);
session.getContext().setAuthenticationSession(logoutSession); session.getContext().setAuthenticationSession(logoutSession);
if (uiLocales != null) { if (uiLocales != null) {
logoutSession.setAuthNote(LocaleSelectorProvider.CLIENT_REQUEST_LOCALE, uiLocales); logoutSession.setClientNote(LocaleSelectorProvider.CLIENT_REQUEST_LOCALE, uiLocales);
} }
if (validatedRedirectUri != null) { if (validatedRedirectUri != null) {
logoutSession.setAuthNote(OIDCLoginProtocol.LOGOUT_REDIRECT_URI, validatedRedirectUri); logoutSession.setAuthNote(OIDCLoginProtocol.LOGOUT_REDIRECT_URI, validatedRedirectUri);

View file

@ -580,10 +580,12 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
boolean forwardedPassiveLogin = "true".equals(authenticationSession.getAuthNote(AuthenticationProcessor.FORWARDED_PASSIVE_LOGIN)); boolean forwardedPassiveLogin = "true".equals(authenticationSession.getAuthNote(AuthenticationProcessor.FORWARDED_PASSIVE_LOGIN));
Map<String, String> extractedAuthNotes = extractAuthNotesFromSession(authenticationSession); String userRequestedLocale = authenticationSession.getAuthNote(LocaleSelectorProvider.USER_REQUEST_LOCALE);
// Redirect to firstBrokerLogin after successful login and ensure that previous authentication state removed // Redirect to firstBrokerLogin after successful login and ensure that previous authentication state removed
AuthenticationProcessor.resetFlow(authenticationSession, LoginActionsService.FIRST_BROKER_LOGIN_PATH); 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. // Set the FORWARDED_PASSIVE_LOGIN note (if needed) after resetting the session so it is not lost.
if (forwardedPassiveLogin) { if (forwardedPassiveLogin) {
@ -616,18 +618,6 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
} }
} }
private Map<String, String> 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) { public Response validateUser(AuthenticationSessionModel authSession, UserModel user, RealmModel realm) {
if (!user.isEnabled()) { if (!user.isEnabled()) {

View file

@ -45,6 +45,7 @@ import org.keycloak.testsuite.util.DroneUtils;
import org.keycloak.testsuite.util.GreenMailRule; import org.keycloak.testsuite.util.GreenMailRule;
import org.keycloak.testsuite.util.MailUtils; import org.keycloak.testsuite.util.MailUtils;
import org.keycloak.testsuite.util.WaitUtils; import org.keycloak.testsuite.util.WaitUtils;
import org.openqa.selenium.By;
/** /**
* @author <a href="mailto:gerbermichi@me.com">Michael Gerber</a> * @author <a href="mailto:gerbermichi@me.com">Michael Gerber</a>
@ -190,4 +191,25 @@ public class EmailTest extends AbstractI18NTest {
assertThat(infoPage.getInfo(), containsString("Your account has been updated.")); 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());
}
} }