8000 Log out other sessions only after the passkey is saved by marsluca · Pull Request #54776 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,6 @@ public void processAction(RequiredActionContext context) {

RegistrationParameters registrationParameters = new RegistrationParameters(serverProperty, buildExpectedCredentialParameters(policy), isUserVerificationRequired);

if ("on".equals(params.getFirst("logout-sessions"))) {
AuthenticatorUtil.logoutOtherSessions(context);
}

WebAuthnRegistrationManager webAuthnRegistrationManager = createWebAuthnRegistrationManager(policy);
try {
// parse
Expand All @@ -340,6 +336,10 @@ public void processAction(RequiredActionContext context) {

CredentialModel createdCredential = webAuthnCredProvider.createCredential(context.getRealm(), context.getUser(), newCredentialModel);

if ("on".equals(params.getFirst("logout-sessions"))) {
AuthenticatorUtil.logoutOtherSessions(context);
}
Comment thread
marsluca marked this conversation as resolved.
Resolved

String aaguid = newCredentialModel.getWebAuth 8000 nCredentialData().getAaguid();
logger.debugv("WebAuthn credential registration success for user {0}. credentialType = {1}, publicKeyCredentialId = {2}, publicKeyCredentialLabel = {3}, publicKeyCredentialAAGUID = {4}",
context.getUser().getUsername(), getCredentialType(), publicKeyCredentialId, label, aaguid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,15 @@
import org.keycloak.testsuite.webauthn.authenticators.DefaultVirtualAuthOptions;
import org.keycloak.testsuite.webauthn.authenticators.UseVirtualAuthenticators;
import org.keycloak.testsuite.webauthn.authenticators.VirtualAuthenticatorManager;
import org.keycloak.testsuite.webauthn.pages.WebAuthnErrorPage;
import org.keycloak.testsuite.webauthn.pages.WebAuthnRegisterPage;

import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

Expand Down Expand Up @@ -88,6 +90,9 @@ public class AppInitiatedActionWebAuthnTest extends AbstractAppInitiatedActionTe
@Page
WebAuthnRegisterPage webAuthnRegisterPage;

@Page
WebAuthnErrorPage webAuthnErrorPage;

@Drone
@SecondBrowser
private WebDriver driver2;
Expand Down Expand Up @@ -182,21 +187,31 @@ public void proceedSetupWebAuthnLogoutOtherSessionsNotChecked() throws IOExcepti
testWebAuthnLogoutOtherSessions(false);
}

protected void testWebAuthnLogoutOtherSessions(boolean logoutOtherSessions) throws IOException {
@Test
@IgnoreBrowserDriver(FirefoxDriver.class) // See https://github.com/keycloak/keycloak/issues/10368
public void failedSetupWebAuthnKeepsOtherSessions() throws IOException {
UserResource testUser = managedRealm.admin().users().get(findUser(DEFAULT_USERNAME).getId());
loginInSecondBrowser(testUser);
loginUser();
assertEquals(2, testUser.getUserSessions().size());

// perform a login using normal user/password form to have an old session
EventRepresentation event1;
try (RealmAttributeUpdater rau = new RealmAttributeUpdater(managedRealm.admin())
.setBrowserFlow("browser")
.update()) {
OAuthClient oauth2 = oauth.newConfig().driver(driver2);
oauth2.doLogin(DEFAULT_USERNAME, getPassword(DEFAULT_USERNAME));
event1 = events.poll();
EventAssertion.expectLoginSuccess(event1);
assertEquals(1, testUser.getUserSessions().size());
}
doAIA();

webAuthnRegisterPage.assertCurrent();
webAuthnRegisterPage.checkLogoutSessions();
// send an invalid attestation so that the server rejects the registration
((JavascriptExecutor) driver).executeScript("document.getElementById('register').addEventListener('submit', function() {"
+ " document.getElementById('attestationObject').value = 'AAAA'; });");
webAuthnRegisterPage.clickRegister();
webAuthnRegisterPage.registerWebAuthnCredential("authenticator1");

webAuthnErrorPage.assertCurrent();
assertThat(testUser.ge 8000 tUserSessions().size(), is(2));
}

protected void testWebAuthnLogoutOtherSessions(boolean logoutOtherSessions) throws IOException {
UserResource testUser = managedRealm.admin().users().get(findUser(DEFAULT_USERNAME).getId());
EventRepresentation event1 = loginInSecondBrowser(testUser);
EventRepresentation event2 = loginUser();
assertEquals(2, testUser.getUserSessions().size());

Expand Down Expand Up @@ -232,6 +247,20 @@ protected void testWebAuthnLogoutOtherSessions(boolean logoutOtherSessions) thro
}
}

// perform a login using normal user/password form to have an old session
private EventRepresentation loginInSecondBrowser(UserResource testUser) throws IOException {
try (RealmAttributeUpdater rau = new RealmAttributeUpdater(managedRealm.admin())
.setBrowserFlow("browser")
.update()) {
OAuthClient oauth2 = oauth.newConfig().driver(driver2);
oauth2.doLogin(DEFAULT_USERNAME, getPassword(DEFAULT_USERNAME));
EventRepresentation event = events.poll();
EventAssertion.expectLoginSuccess(event);
assertEquals(1, testUser.getUserSessions().size());
return event;
}
}

private EventRepresentation loginUser() {
oauth.openLoginForm();
usernamePage.assertCurrent();
Expand Down
Loading
0