From 18d0105de00eea06696c0abcb520e21ec1fc1416 Mon Sep 17 00:00:00 2001 From: Douglas Palmer Date: Sat, 13 Jan 2024 09:35:54 -0800 Subject: [PATCH] Invalidate authentication session on repeated OTP failures Closes #26177 Signed-off-by: Douglas Palmer --- .../browser/OTPFormAuthenticator.java | 2 ++ .../keycloak/testsuite/forms/BruteForceTest.java | 16 +++++++--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/browser/OTPFormAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/browser/OTPFormAuthenticator.java index f517e7f114..37649c7cf6 100755 --- a/services/src/main/java/org/keycloak/authentication/authenticators/browser/OTPFormAuthenticator.java +++ b/services/src/main/java/org/keycloak/authentication/authenticators/browser/OTPFormAuthenticator.java @@ -35,6 +35,7 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserModel; import org.keycloak.models.credential.OTPCredentialModel; +import org.keycloak.services.managers.AuthenticationSessionManager; import org.keycloak.services.messages.Messages; import org.keycloak.services.validation.Validation; import org.keycloak.sessions.AuthenticationSessionModel; @@ -89,6 +90,7 @@ public class OTPFormAuthenticator extends AbstractUsernameFormAuthenticator impl UserModel userModel = context.getUser(); if (!enabledUser(context, userModel)) { // error in context is set in enabledUser/isDisabledByBruteForce + new AuthenticationSessionManager(context.getSession()).removeAuthenticationSession(context.getRealm(), context.getAuthenticationSession(), true); return; } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BruteForceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BruteForceTest.java index a21f89adcc..dca0a3a755 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BruteForceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BruteForceTest.java @@ -455,9 +455,6 @@ public class BruteForceTest extends AbstractTestRealmKeycloakTest { loginInvalidPassword(); loginWithTotpFailure(); continueLoginWithCorrectTotpExpectFailure(); - continueLoginWithInvalidTotp(); - clearUserFailures(); - continueLoginWithTotp(); } @Test @@ -466,13 +463,14 @@ public class BruteForceTest extends AbstractTestRealmKeycloakTest { loginWithMissingTotp(); loginWithMissingTotp(); continueLoginWithMissingTotp(); - continueLoginWithCorrectTotpExpectFailure(); - // wait to unlock - testingClient.testing().setTimeOffset(Collections.singletonMap("offset", String.valueOf(6))); + } - continueLoginWithTotp(); - - testingClient.testing().setTimeOffset(Collections.singletonMap("offset", String.valueOf(0))); + @Test + public void testBrowserTotpSessionClosedAfterLockout() throws Exception { + long start = System.currentTimeMillis(); + loginWithTotpFailure(); + continueLoginWithInvalidTotp(); + loginPage.assertCurrent(); } @Test