8000 Remove root auth session after backchannel logout by graziang · Pull Request #33437 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Merged
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
8000
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,7 @@ public static BackchannelLogoutResponse backchannelLogout(KeycloakSession sessio
checkUserSessionOnlyHasLoggedOutClients(realm, userSession, logoutAuthSession);
} finally {
logger.tracef("Removing logout session '%s' after backchannel logout", logoutAuthSession.getParentSession().getId());
RootAuthenticationSessionModel rootAuthSession = logoutAuthSession.getParentSession();
rootAuthSession.removeAuthenticationSessionByTabId(logoutAuthSession.getTabId());
session.authenticationSessions().removeRootAuthenticationSession(realm, logoutAuthSession.getParentSession());
}

userSession.setState(UserSessionModel.State.LOGGED_OUT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ public static BrowserTabUtil getInstanceAndSetEnv(WebDriver driver) {
return instance;
}

public static void cleanup() {
instances = new ArrayList<>();
}

public WebDriver getDriver() {
return driver;
}
Expand Down Expand Up @@ -155,4 +159,4 @@ private void assertValidIndex(int index) {
public void close() {
destroy();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import org.keycloak.testsuite.auth.page.login.UpdatePassword;
import org.keycloak.testsuite.client.KeycloakTestingClient;
import org.keycloak.testsuite.pages.LoginPasswordUpdatePage;
import org.keycloak.testsuite.util.BrowserTabUtil;
import org.keycloak.testsuite.util.CryptoInitRule;
import org.keycloak.testsuite.util.DroneUtils;
import org.keycloak.testsuite.util.OAuthClient;
Expand Down Expand Up @@ -251,6 +252,7 @@ public void afterAbstractKeycloakTest() throws Exception {

// Remove all browsers from queue
DroneUtils.resetQueue();
BrowserTabUtil.cleanup();
}

protected TestCleanup getCleanup(String realmName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.keycloak.testsuite.pages.LoginTotpPage;
import org.keycloak.testsuite.pages.LoginUsernameOnlyPage;
import org.keycloak.testsuite.pages.PasswordPage;
import org.keycloak.testsuite.util.BrowserTabUtil;
import org.keycloak.testsuite.util.FederatedIdentityBuilder;
import org.keycloak.testsuite.util.FlowUtil;
import org.keycloak.testsuite.util.OAuthClient;
Expand Down Expand Up @@ -366,6 +367,42 @@ public void loginAfterExpiredUserSession() {
realmsResouce().realm(rep.getRealm()).update(rep);
}

@Test
public void loginAfterLogoutWithDifferentSessionId() {
BrowserTabUtil tabUtil = BrowserTabUtil.getInstanceAndSetEnv(driver);

assertThat(tabUtil.getCountOfTabs(), Matchers.is(1));
oauth.openLoginForm();
loginPage.assertCurrent();

tabUtil.newTab(oauth.getLoginFormUrl());
assertThat(tabUtil.getCountOfTabs(), Matchers.equalTo(2));
oauth.openLoginForm();

tabUtil.closeTab(tabUtil.getCountOfTabs() - 1);
assertThat(tabUtil.getCountOfTabs(), Matchers.equalTo(1));

tabUtil.switchToTab(0);
loginPage.assertCurrent();

loginPage.login("test-user@localhost", "password");
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
OAuthClient.AccessTokenResponse response1 = oauth.doAccessTokenRequest(code, "password");
AccessToken accessToken1 = oauth.verifyToken(response1.getAccessToken());

oauth.doLogout(response1.getRefreshToken(), "password");

oauth.openLoginForm();
loginPage.assertCurrent();
loginPage.login("test-user@localhost", "password");
code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
OAuthClient.AccessTokenResponse response2 = oauth.doAccessTokenRequest(code, "password");
AccessToken accessToken2 = oauth.verifyToken(response2.getAccessToken());

Assert.assertNotEquals(accessToken1.getId(), accessToken2.getId());
Assert.assertNotEquals(accessToken1.getSessionId(), accessToken2.getSessionId());
}

private void setupIdentityFirstFlow() {
String newFlowAlias = "browser - identity first";
testingClient.server("test").run(session -> FlowUtil.inCurrentRealm(session).copyBrowserFlow(newFlowAlias));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,30 +146,14 @@ public void postLogoutWithRefreshTokenAfterUserSessionLogoutAndLoginAgain() thro

setTimeOffset(2);

WaitUtils.waitForPageToLoad();
loginPage.login("password");
driver.navigate().refresh();
oauth.fillLoginForm("test-user@localhost", "password");

Assert.assertFalse(loginPage.isCurrent());

String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
OAuthClient.AccessTokenResponse tokenResponse2 = oauth.doAccessTokenRequest(code, "password");

// POST logout with token should fail
try (CloseableHttpResponse response = oauth.doLogout(refreshToken1, "password")) {
assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatusLine().getStatusCode());
}

String logoutUrl = oauth.getLogoutUrl()
.idTokenHint(accessTokenResponse.getIdToken())
.postLogoutRedirectUri(oauth.APP_AUTH_ROOT)
.build();

// GET logout with ID token should fail as well
try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build();
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatusLine().getStatusCode());
}

// finally POST logout with VALID token should succeed
try (CloseableHttpResponse response = oauth.doLogout(tokenResponse2.getRefreshToken(), "password")) {
MatcherAssert.assertThat(response, Matchers.statusCodeIsHC(Status.NO_CONTENT));
Expand All @@ -178,7 +162,6 @@ public void postLogoutWithRefreshTokenAfterUserSessionLogoutAndLoginAgain() thro
}
}


@Test
public void postLogoutFailWithCredentialsOfDifferentClient() throws Exception {
oauth.doLogin("test-user@localhost", "password");
Expand Down Expand Up @@ -247,7 +230,7 @@ private void backchannelLogoutRequest(String expectedRefreshAlg, String expected
.idTokenHint(idTokenString)
.postLogoutRedirectUri(oauth.APP_AUTH_ROOT)
.build();

try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build();
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
MatcherAssert.assertThat(response, Matchers.statusCodeIsHC(Status.FOUND));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1067,8 +1067,8 @@ public void refreshTokenAfterUserLogoutAndLoginAgain() {
try {
// Continue with login
setTimeOffset(2);
WaitUtils.waitForPageToLoad();
loginPage.login("password");
driver.navigate().refresh();
oauth.fillLoginForm("test-user@localhost", "password");

assertFalse(loginPage.isCurrent());

Expand Down Expand Up @@ -1101,8 +1101,8 @@ public void refreshTokenAfterAdminLogoutAllAndLoginAgain() {
try {
// Continue with login
setTimeOffset(2);
WaitUtils.waitForPageToLoad();
loginPage.login("password");
driver.navigate().refresh();
oauth.fillLoginForm("test-user@localhost", "password");

assertFalse(loginPage.isCurrent());

Expand Down Expand Up @@ -1134,8 +1134,8 @@ public void refreshTokenAfterUserAdminLogoutEndpointAndLoginAgain() {

// Continue with login
setTimeOffset(2);
WaitUtils.waitForPageToLoad();
loginPage.login("password");
driver.navigate().refresh();
oauth.fillLoginForm("test-user@localhost", "password");

assertFalse(loginPage.isCurrent());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,8 @@ public void testIntrospectRefreshTokenAfterUserSessionLogoutAndLoginAgain() thro

setTimeOffset(2);

WaitUtils.waitForPageToLoad();
loginPage.login("password");
driver.navigate().refresh();
oauth.fillLoginForm("test-user@localhost", "password");
events.expectLogin().assertEvent();

Assert.assertFalse(loginPage.isCurrent());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ public void testSuccess_postMethod_body() throws Exception {
client.close();
}
}

@Test
public void testSuccess_postMethod_charset_body() throws Exception {
Client client = AdminClientUtil.createResteasyClient();
Expand Down Expand Up @@ -531,7 +531,7 @@ public void testSuccessSignedResponsePS256() throws Exception {
public void testSuccessSignedResponseRS256AcceptJWT() throws Exception {
testSuccessSignedResponse(Algorithm.RS256, MediaType.APPLICATION_JWT);
}

@Test
public void testSessionExpired() {
Client client = AdminClientUtil.createResteasyClient();
Expand Down Expand Up @@ -607,8 +607,8 @@ public void testAccessTokenAfterUserSessionLogoutAndLoginAgain() {

setTimeOffset(2);

WaitUtils.waitForPageToLoad();
loginPage.login("password");
driver.navigate().refresh();
oauth.fillLoginForm("test-user@localhost", "password");
events.expectLogin().assertEvent();

Assert.assertFalse(loginPage.isCurrent());
Expand All @@ -630,7 +630,7 @@ public void testAccessTokenAfterUserSessionLogoutAndLoginAgain() {
response.close();

events.expect(EventType.USER_INFO_REQUEST_ERROR)
.error(Errors.INVALID_TOKEN)
.error(Errors.USER_SESSION_NOT_FOUND)
.user(Matchers.nullValue(String.class))
.session(Matchers.nullValue(String.class))
.detail(Details.AUTH_METHOD, Details.VALIDATE_ACCESS_TOKEN)
Expand Down Expand Up @@ -1088,23 +1088,23 @@ private void testRolesAreNotInUserInfoResponse(UserInfo userInfo) {
assertNull(userInfo.getOtherClaims().get("realm_access"));
assertNull(userInfo.getOtherClaims().get("resource_access"));
}

@Test
public void test_noContentType() throws Exception {
Client client = AdminClientUtil.createResteasyClient();

try {
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);

WebTarget userInfoTarget = UserInfoClientUtil.getUserInfoWebTarget(client);
Response response = userInfoTarget.request()
.header(HttpHeaders.AUTHORIZATION, "bearer " + accessTokenResponse.getToken())
.build("POST")
.invoke();

Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("OK", response.getStatusInfo().toString());

} finally {
client.close();
}
Expand Down
0