Flow steps back when changing locale or refreshing page on 'Try another way page'
closes #30520 Signed-off-by: mposolda <mposolda@gmail.com>
This commit is contained in:
parent
592c2250fc
commit
6a9e60bba0
3 changed files with 62 additions and 7 deletions
|
@ -90,6 +90,9 @@ public class AuthenticationProcessor {
|
|||
public static final String BROKER_USER_ID = "broker.user.id";
|
||||
public static final String FORWARDED_PASSIVE_LOGIN = "forwarded.passive.login";
|
||||
|
||||
// Boolean flag, which is true when authentication-selector screen should be rendered (typically displayed when user clicked on 'try another way' link)
|
||||
public static final String AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED = "auth.selector.screen.rendered";
|
||||
|
||||
protected static final Logger logger = Logger.getLogger(AuthenticationProcessor.class);
|
||||
protected RealmModel realm;
|
||||
protected UserSessionModel userSession;
|
||||
|
@ -429,7 +432,7 @@ public class AuthenticationProcessor {
|
|||
this.challenge = challenge;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void failure(AuthenticationFlowError error, Response challenge, String eventDetails, String userErrorMessage) {
|
||||
this.error = error;
|
||||
|
@ -1164,7 +1167,7 @@ public class AuthenticationProcessor {
|
|||
if (!authenticatedUser.isEnabled()) throw new AuthenticationFlowException(AuthenticationFlowError.USER_DISABLED);
|
||||
if (authenticatedUser.getServiceAccountClientLink() != null) throw new AuthenticationFlowException(AuthenticationFlowError.UNKNOWN_USER);
|
||||
}
|
||||
|
||||
|
||||
protected Response authenticationComplete() {
|
||||
// attachSession(); // Session will be attached after requiredActions + consents are finished.
|
||||
AuthenticationManager.setClientScopesInSession(authenticationSession);
|
||||
|
|
|
@ -93,16 +93,14 @@ public class DefaultAuthenticationFlow implements AuthenticationFlow {
|
|||
if (inputData.containsKey("tryAnotherWay")) {
|
||||
logger.trace("User clicked on link 'Try Another Way'");
|
||||
|
||||
List<AuthenticationSelectionOption> selectionOptions = createAuthenticationSelectionList(model);
|
||||
|
||||
AuthenticationProcessor.Result result = processor.createAuthenticatorContext(model, null, null);
|
||||
result.setAuthenticationSelections(selectionOptions);
|
||||
return result.form().createSelectAuthenticator();
|
||||
processor.getAuthenticationSession().setAuthNote(AuthenticationProcessor.AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED, "true");
|
||||
return createSelectAuthenticatorsScreen(model);
|
||||
}
|
||||
|
||||
// check if the user has switched to a new authentication execution, and if so switch to it.
|
||||
if (authExecId != null && !authExecId.isEmpty()) {
|
||||
|
||||
processor.getAuthenticationSession().removeAuthNote(AuthenticationProcessor.AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED);
|
||||
List<AuthenticationSelectionOption> selectionOptions = createAuthenticationSelectionList(model);
|
||||
|
||||
// Check if switch to the requested authentication execution is allowed
|
||||
|
@ -222,10 +220,35 @@ public class DefaultAuthenticationFlow implements AuthenticationFlow {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create screen where user can select from multiple authentication methods (Usually displayed when user clicks on 'try another way' link during authentication)
|
||||
*
|
||||
* @param executionModel Last execution (should be typically available in the methods)
|
||||
* @return response with the screen to be displayed to the user
|
||||
*/
|
||||
private Response createSelectAuthenticatorsScreen(AuthenticationExecutionModel executionModel) {
|
||||
List<AuthenticationSelectionOption> selectionOptions = createAuthenticationSelectionList(executionModel);
|
||||
|
||||
AuthenticationProcessor.Result result = processor.createAuthenticatorContext(executionModel, null, null);
|
||||
result.setAuthenticationSelections(selectionOptions);
|
||||
return result.form().createSelectAuthenticator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response processFlow() {
|
||||
logger.debugf("processFlow: %s", flow.getAlias());
|
||||
|
||||
if (Boolean.parseBoolean(processor.getAuthenticationSession().getAuthNote(AuthenticationProcessor.AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED))) {
|
||||
logger.tracef("Refreshed page on authentication selector screen");
|
||||
String lastExecutionId = processor.getAuthenticationSession().getAuthNote(AuthenticationProcessor.CURRENT_AUTHENTICATION_EXECUTION);
|
||||
if (lastExecutionId != null) {
|
||||
AuthenticationExecutionModel executionModel = processor.getRealm().getAuthenticationExecutionById(lastExecutionId);
|
||||
if (executionModel != null) {
|
||||
return createSelectAuthenticatorsScreen(executionModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//separate flow elements into required and alternative elements
|
||||
List<AuthenticationExecutionModel> requiredList = new ArrayList<>();
|
||||
List<AuthenticationExecutionModel> alternativeList = new ArrayList<>();
|
||||
|
|
|
@ -159,6 +159,35 @@ public class MultiFactorAuthenticationTest extends AbstractTestRealmKeycloakTest
|
|||
}
|
||||
}
|
||||
|
||||
// Issue https://github.com/keycloak/keycloak/issues/30520
|
||||
@Test
|
||||
public void testChangingLocaleOnAuthenticationSelectorScreen() {
|
||||
try {
|
||||
configureBrowserFlowWithAlternativeCredentials();
|
||||
|
||||
loginUsernameOnlyPage.open();
|
||||
loginUsernameOnlyPage.login("user-with-one-configured-otp");
|
||||
passwordPage.assertCurrent();
|
||||
passwordPage.assertTryAnotherWayLinkAvailability(true);
|
||||
passwordPage.clickTryAnotherWayLink();
|
||||
|
||||
selectAuthenticatorPage.assertCurrent();
|
||||
Assert.assertEquals(Arrays.asList(SelectAuthenticatorPage.PASSWORD, SelectAuthenticatorPage.AUTHENTICATOR_APPLICATION), selectAuthenticatorPage.getAvailableLoginMethods());
|
||||
|
||||
// Switch locale. Should be still on "selectAuthenticatorPage"
|
||||
selectAuthenticatorPage.openLanguage("Deutsch");
|
||||
selectAuthenticatorPage.assertCurrent();
|
||||
Assert.assertEquals(Arrays.asList("Passwort", "Authenticator-Anwendung"), selectAuthenticatorPage.getAvailableLoginMethods());
|
||||
|
||||
// Change language back
|
||||
selectAuthenticatorPage.openLanguage("English");
|
||||
selectAuthenticatorPage.assertCurrent();
|
||||
Assert.assertEquals(Arrays.asList(SelectAuthenticatorPage.PASSWORD, SelectAuthenticatorPage.AUTHENTICATOR_APPLICATION), selectAuthenticatorPage.getAvailableLoginMethods());
|
||||
} finally {
|
||||
BrowserFlowTest.revertFlows(testRealm(), "browser - alternative");
|
||||
}
|
||||
}
|
||||
|
||||
private void configureBrowserFlowWithAlternativeCredentials() {
|
||||
configureBrowserFlowWithAlternativeCredentials(testingClient);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue