feat: organization authenticator : bypass username form when login_hint is set

Closes #38228

Signed-off-by: Olivier Boudet <o.boudet@gmail.com>
This commit is contained in:
Olivier Boudet 2025-05-05 18:37:48 +02:00 committed by GitHub
parent 3e05f676e5
commit a39a64e4d1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 2 deletions

View File

@ -23,6 +23,7 @@ import static org.keycloak.models.utils.KeycloakModelUtils.findUserByNameOrEmail
import static org.keycloak.organization.utils.Organizations.getEmailDomain;
import static org.keycloak.organization.utils.Organizations.isEnabledAndOrganizationsPresent;
import static org.keycloak.organization.utils.Organizations.resolveHomeBroker;
import static org.keycloak.utils.StringUtil.isNotBlank;
import java.util.List;
import java.util.Map;
@ -64,6 +65,8 @@ import org.keycloak.sessions.AuthenticationSessionModel;
public class OrganizationAuthenticator extends IdentityProviderAuthenticator {
private static final String LOGIN_HINT_ALREADY_HANDLED = "loginHintAlreadyHandled";
private final KeycloakSession session;
public OrganizationAuthenticator(KeycloakSession session) {
@ -79,6 +82,16 @@ public class OrganizationAuthenticator extends IdentityProviderAuthenticator {
return;
}
String loginHint = session.getContext().getAuthenticationSession().getClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM);
if (isNotBlank(loginHint) && !"true".equals(context.getAuthenticationSession().getClientNote(LOGIN_HINT_ALREADY_HANDLED))) {
UserModel user = resolveUser(context, loginHint);
context.setUser(user);
// set auth note to true to handle login_hint only once, we don't want to handle it again after a flow restart
context.getAuthenticationSession().setClientNote(LOGIN_HINT_ALREADY_HANDLED, "true");
}
OrganizationModel organization = Organizations.resolveOrganization(session);
if (organization == null) {

View File

@ -205,10 +205,9 @@ public class OrganizationAuthenticationTest extends AbstractOrganizationTest {
String expectedUsername = URLEncoder.encode(member.getEmail(), StandardCharsets.UTF_8);
oauth.realm(bc.consumerRealmName());
oauth.loginForm().loginHint(expectedUsername).open();
assertThat(loginPage.getUsername(), Matchers.equalTo(URLDecoder.decode(expectedUsername, StandardCharsets.UTF_8)));
assertThat(loginPage.getAttemptedUsername(), Matchers.equalTo(URLDecoder.decode(expectedUsername, StandardCharsets.UTF_8)));
// continue authenticating without setting the username
loginPage.clickSignIn();
loginPage.login(memberPassword);
appPage.assertCurrent();
}