Auth not possible for auth session where user was enabled in the meantime

Closes #33883

Signed-off-by: Martin Kanis <mkanis@redhat.com>
This commit is contained in:
Martin Kanis 2024-10-14 11:26:51 +02:00 committed by Pedro Igor
parent 74caf48b63
commit 8fb5ecaa6c
3 changed files with 22 additions and 9 deletions

View file

@ -87,13 +87,17 @@ public class OTPFormAuthenticator extends AbstractUsernameFormAuthenticator impl
context.form().setAttribute(SELECTED_OTP_CREDENTIAL_ID, credentialId); context.form().setAttribute(SELECTED_OTP_CREDENTIAL_ID, credentialId);
UserModel userModel = context.getUser(); UserModel userModel = context.getUser();
boolean userEnabled = enabledUser(context, userModel);
// the brute force lock might be lifted/user enabled in the meantime -> we need to clear the auth session note
if (userEnabled) {
context.getAuthenticationSession().removeAuthNote(AbstractUsernameFormAuthenticator.SESSION_INVALID);
}
if("true".equals(context.getAuthenticationSession().getAuthNote(AbstractUsernameFormAuthenticator.SESSION_INVALID))) { if("true".equals(context.getAuthenticationSession().getAuthNote(AbstractUsernameFormAuthenticator.SESSION_INVALID))) {
context.getEvent().user(context.getUser()).error(Errors.INVALID_AUTHENTICATION_SESSION); context.getEvent().user(context.getUser()).error(Errors.INVALID_AUTHENTICATION_SESSION);
Response challengeResponse = challenge(context, Messages.INVALID_TOTP, Validation.FIELD_OTP_CODE); // challenge already set by calling enabledUser() above
context.forceChallenge(challengeResponse);
return; return;
} }
if (!enabledUser(context, userModel)) { if (!userEnabled) {
// error in context is set in enabledUser/isDisabledByBruteForce // error in context is set in enabledUser/isDisabledByBruteForce
context.getAuthenticationSession().setAuthNote(AbstractUsernameFormAuthenticator.SESSION_INVALID, "true"); context.getAuthenticationSession().setAuthNote(AbstractUsernameFormAuthenticator.SESSION_INVALID, "true");
return; return;

View file

@ -48,15 +48,22 @@ public class RecoveryAuthnCodesFormAuthenticator implements Authenticator {
MultivaluedMap<String, String> formParamsMap = authnFlowContext.getHttpRequest().getDecodedFormParameters(); MultivaluedMap<String, String> formParamsMap = authnFlowContext.getHttpRequest().getDecodedFormParameters();
String recoveryAuthnCodeUserInput = formParamsMap.getFirst(RecoveryAuthnCodesUtils.FIELD_RECOVERY_CODE_IN_BROWSER_FLOW); String recoveryAuthnCodeUserInput = formParamsMap.getFirst(RecoveryAuthnCodesUtils.FIELD_RECOVERY_CODE_IN_BROWSER_FLOW);
UserModel authenticatedUser = authnFlowContext.getUser();
boolean disabledByBruteForce = isDisabledByBruteForce(authnFlowContext, authenticatedUser);
if (ObjectUtil.isBlank(recoveryAuthnCodeUserInput) if (ObjectUtil.isBlank(recoveryAuthnCodeUserInput)
|| "true".equals(authnFlowContext.getAuthenticationSession().getAuthNote(AbstractUsernameFormAuthenticator.SESSION_INVALID))) { || "true".equals(authnFlowContext.getAuthenticationSession().getAuthNote(AbstractUsernameFormAuthenticator.SESSION_INVALID))) {
// the brute force lock might be lifted in the meantime -> we need to clear the auth session note
if (!disabledByBruteForce) {
authnFlowContext.getAuthenticationSession().removeAuthNote(AbstractUsernameFormAuthenticator.SESSION_INVALID);
} else {
authnFlowContext.forceChallenge(createLoginForm(authnFlowContext, true, authnFlowContext.forceChallenge(createLoginForm(authnFlowContext, true,
RecoveryAuthnCodesUtils.RECOVERY_AUTHN_CODES_INPUT_DEFAULT_ERROR_MESSAGE, RecoveryAuthnCodesUtils.RECOVERY_AUTHN_CODES_INPUT_DEFAULT_ERROR_MESSAGE,
RecoveryAuthnCodesUtils.FIELD_RECOVERY_CODE_IN_BROWSER_FLOW)); RecoveryAuthnCodesUtils.FIELD_RECOVERY_CODE_IN_BROWSER_FLOW));
return result; return result;
} }
UserModel authenticatedUser = authnFlowContext.getUser(); }
if (!isDisabledByBruteForce(authnFlowContext, authenticatedUser)) {
if (!disabledByBruteForce) {
boolean isValid = authenticatedUser.credentialManager().isValid( boolean isValid = authenticatedUser.credentialManager().isValid(
UserCredentialModel.buildFromBackupAuthnCode(recoveryAuthnCodeUserInput.replace("-", ""))); UserCredentialModel.buildFromBackupAuthnCode(recoveryAuthnCodeUserInput.replace("-", "")));
if (!isValid) { if (!isValid) {

View file

@ -595,6 +595,8 @@ public abstract class AbstractAdvancedBrokerTest extends AbstractBrokerTest {
setOtpTimeOffset(TimeBasedOTP.DEFAULT_INTERVAL_SECONDS, totp); setOtpTimeOffset(TimeBasedOTP.DEFAULT_INTERVAL_SECONDS, totp);
loginTotpPage.login(totp.generateTOTP(totpSecret)); loginTotpPage.login(totp.generateTOTP(totpSecret));
WaitUtils.waitForPageToLoad();
appPage.assertCurrent();
AccountHelper.logout(adminClient.realm(bc.consumerRealmName()), bc.getUserLogin()); AccountHelper.logout(adminClient.realm(bc.consumerRealmName()), bc.getUserLogin());
} finally { } finally {
testingClient.server(bc.consumerRealmName()).run(disablePostBrokerLoginFlow(bc.getIDPAlias())); testingClient.server(bc.consumerRealmName()).run(disablePostBrokerLoginFlow(bc.getIDPAlias()));