Remove authentication session when deleting the account

Closes #38671

Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
Pedro Igor
2025-04-30 05:27:23 -03:00
committed by GitHub
parent c9b5ac4d6c
commit 89b66cd3a7
2 changed files with 53 additions and 2 deletions

View File

@@ -42,7 +42,9 @@ import org.keycloak.models.RoleModel;
import org.keycloak.models.UserManager;
import org.keycloak.models.UserModel;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.AuthenticationSessionManager;
import org.keycloak.services.messages.Messages;
import org.keycloak.sessions.AuthenticationSessionModel;
public class DeleteAccount implements RequiredActionProvider, RequiredActionFactory {
@@ -94,7 +96,7 @@ public class DeleteAccount implements RequiredActionProvider, RequiredActionFact
.detail(Details.USERNAME, user.getUsername())
.success();
cleanSession(context, RequiredActionContext.KcActionStatus.SUCCESS);
removeAuthenticationSession(context, session);
context.challenge(context.form()
.setAttribute("messageHeader", "")
@@ -185,4 +187,9 @@ public class DeleteAccount implements RequiredActionProvider, RequiredActionFact
public int getMaxAuthAge() {
return 0;
}
private void removeAuthenticationSession(RequiredActionContext context, KeycloakSession session) {
AuthenticationSessionModel authSession = context.getAuthenticationSession();
new AuthenticationSessionManager(session).removeAuthenticationSession(authSession.getRealm(), authSession, true);
}
}

View File

@@ -11,6 +11,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.authentication.requiredactions.DeleteAccount;
import org.keycloak.cookie.CookieType;
import org.keycloak.events.EventType;
import org.keycloak.models.AccountRoles;
import org.keycloak.representations.idm.ClientRepresentation;
@@ -25,6 +26,7 @@ import org.keycloak.testsuite.auth.page.login.DeleteAccountActionConfirmPage;
import org.keycloak.testsuite.pages.ErrorPage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.util.UserBuilder;
import org.openqa.selenium.Cookie;
public class DeleteAccountActionTest extends AbstractTestRealmKeycloakTest {
@@ -73,6 +75,44 @@ public class DeleteAccountActionTest extends AbstractTestRealmKeycloakTest {
Assert.assertEquals(users.size(), 0);
}
@Test
public void testReauthenticateAfterDeletingAccount() {
loginPage.open();
UserRepresentation userRep = UserBuilder.create()
.username("delete-user")
.password("password")
.enabled(true)
.requiredAction(DeleteAccount.PROVIDER_ID)
.build();
testRealm().users().create(userRep).close();
addDeleteAccountRoleToUserClientRoles(userRep.getUsername());
loginPage.login(userRep.getUsername(), "password");
Assert.assertTrue(deleteAccountPage.isCurrent());
Cookie authSessionCookie = driver.manage().getCookieNamed(CookieType.AUTH_SESSION_ID.getName());
deleteAccountPage.clickConfirmAction();
events.expect(EventType.DELETE_ACCOUNT);
List<UserRepresentation> users = testRealm().users().search(userRep.getUsername());
Assert.assertEquals(users.size(), 0);
testRealm().users().create(userRep).close();
addDeleteAccountRoleToUserClientRoles(userRep.getUsername());
loginPage.open();
Cookie newAuthSessionCookie = driver.manage().getCookieNamed(CookieType.AUTH_SESSION_ID.getName());
Assert.assertFalse(authSessionCookie.getValue().equals(newAuthSessionCookie.getValue()));
loginPage.login(userRep.getUsername(), "password");
Assert.assertTrue(deleteAccountPage.isCurrent());
deleteAccountPage.clickConfirmAction();
users = testRealm().users().search(userRep.getUsername());
Assert.assertEquals(users.size(), 0);
}
@Test
public void deleteAccountFailsWithoutRoleFails() {
removeDeleteAccountRoleFromUserClientRoles();
@@ -87,7 +127,11 @@ public class DeleteAccountActionTest extends AbstractTestRealmKeycloakTest {
private void addDeleteAccountRoleToUserClientRoles() {
UserRepresentation user = ActionUtil.findUserWithAdminClient(adminClient, "test-user@localhost");
addDeleteAccountRoleToUserClientRoles("test-user@localhost");
}
private void addDeleteAccountRoleToUserClientRoles(String username) {
UserRepresentation user = ActionUtil.findUserWithAdminClient(adminClient, username);
ApiUtil.assignClientRoles(adminClient.realm("test"), user.getId(), "account", AccountRoles.DELETE_ACCOUNT);
}