Logout from all clients after IdP logout is performed
Closes #25234 Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
parent
22da43c619
commit
7d05a7a013
3 changed files with 59 additions and 10 deletions
|
@ -645,16 +645,11 @@ public class AuthenticationManager {
|
|||
final AuthenticationSessionManager asm = new AuthenticationSessionManager(session);
|
||||
AuthenticationSessionModel logoutAuthSession = createOrJoinLogoutSession(session, realm, asm, userSession, true);
|
||||
|
||||
Response response = browserLogoutAllClients(userSession, session, realm, headers, uriInfo, logoutAuthSession);
|
||||
if (response != null) {
|
||||
return response;
|
||||
}
|
||||
|
||||
String brokerId = userSession.getNote(Details.IDENTITY_PROVIDER);
|
||||
String initiatingIdp = logoutAuthSession.getAuthNote(AuthenticationManager.LOGOUT_INITIATING_IDP);
|
||||
if (brokerId != null && !brokerId.equals(initiatingIdp)) {
|
||||
IdentityProvider identityProvider = IdentityBrokerService.getIdentityProvider(session, realm, brokerId);
|
||||
response = identityProvider.keycloakInitiatedBrowserLogout(session, userSession, uriInfo, realm);
|
||||
Response response = identityProvider.keycloakInitiatedBrowserLogout(session, userSession, uriInfo, realm);
|
||||
if (response != null) {
|
||||
return response;
|
||||
}
|
||||
|
@ -688,6 +683,11 @@ public class AuthenticationManager {
|
|||
final AuthenticationSessionManager asm = new AuthenticationSessionManager(session);
|
||||
AuthenticationSessionModel logoutAuthSession = createOrJoinLogoutSession(session, realm, asm, userSession, true);
|
||||
|
||||
Response response = browserLogoutAllClients(userSession, session, realm, headers, uriInfo, logoutAuthSession);
|
||||
if (response != null) {
|
||||
return response;
|
||||
}
|
||||
|
||||
checkUserSessionOnlyHasLoggedOutClients(realm, userSession, logoutAuthSession);
|
||||
|
||||
// For resolving artifact we don't need any cookie, all details are stored in session storage so we can remove
|
||||
|
@ -703,7 +703,7 @@ public class AuthenticationManager {
|
|||
.setEventBuilder(event);
|
||||
|
||||
|
||||
Response response = protocol.finishBrowserLogout(userSession, logoutAuthSession);
|
||||
response = protocol.finishBrowserLogout(userSession, logoutAuthSession);
|
||||
|
||||
// It may be possible that there are some client sessions that are still in LOGGING_OUT state
|
||||
long numberOfUnconfirmedSessions = userSession.getAuthenticatedClientSessions().values().stream()
|
||||
|
|
|
@ -342,7 +342,7 @@ public abstract class AbstractBaseBrokerTest extends AbstractKeycloakTest {
|
|||
.clientId(clientId)
|
||||
.initiatingIdp(initiatingIdp);
|
||||
|
||||
if (clientId != null || idTokenHint != null) {
|
||||
if (redirectUri != null && (clientId != null || idTokenHint != null)) {
|
||||
builder.postLogoutRedirectUri(encodeUrl(redirectUri));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.keycloak.testsuite.broker;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
|
@ -8,11 +9,14 @@ import org.keycloak.admin.client.resource.IdentityProviderResource;
|
|||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.common.VerificationException;
|
||||
import org.keycloak.cookie.CookieType;
|
||||
import org.keycloak.protocol.oidc.OIDCConfigAttributes;
|
||||
import org.keycloak.representations.IDToken;
|
||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
import org.keycloak.testsuite.updaters.ClientAttributeUpdater;
|
||||
import org.keycloak.testsuite.util.AccountHelper;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.keycloak.testsuite.util.WaitUtils;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_CONS_NAME;
|
||||
|
@ -22,7 +26,6 @@ import static org.keycloak.testsuite.broker.BrokerTestTools.waitForPage;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class KcOidcBrokerLogoutTest extends AbstractKcOidcBrokerLogoutTest {
|
||||
|
||||
|
@ -162,7 +165,6 @@ public class KcOidcBrokerLogoutTest extends AbstractKcOidcBrokerLogoutTest {
|
|||
identityProviderResource.update(representation);
|
||||
logInAsUserInIDPForFirstTime();
|
||||
appPage.assertCurrent();
|
||||
driver.manage().timeouts().pageLoadTimeout(1, TimeUnit.DAYS);
|
||||
executeLogoutFromRealm(
|
||||
getConsumerRoot(),
|
||||
bc.consumerRealmName(),
|
||||
|
@ -231,4 +233,51 @@ public class KcOidcBrokerLogoutTest extends AbstractKcOidcBrokerLogoutTest {
|
|||
identityProviderResource.update(representation);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFrontChannelLogoutRequestsSendingOnlyClientIdWithFrontChannelLogoutApp() throws Exception {
|
||||
RealmResource realm = adminClient.realm(bc.consumerRealmName());
|
||||
IdentityProviderResource identityProviderResource = realm.identityProviders().get(bc.getIDPAlias());
|
||||
IdentityProviderRepresentation representation = identityProviderResource.toRepresentation();
|
||||
Map<String, String> config = representation.getConfig();
|
||||
Map<String, String> originalConfig = new HashMap<>(config);
|
||||
|
||||
try (ClientAttributeUpdater clientUpdater = ClientAttributeUpdater.forClient(adminClient, bc.consumerRealmName(), "broker-app")
|
||||
.setFrontchannelLogout(true)
|
||||
.setAttribute(OIDCConfigAttributes.FRONT_CHANNEL_LOGOUT_URI, getConsumerRoot() + "/auth/realms/" + bc.consumerRealmName() + "/app/logout")
|
||||
.update()){
|
||||
config.put("backchannelSupported", Boolean.FALSE.toString());
|
||||
config.put("sendIdTokenOnLogout", Boolean.FALSE.toString());
|
||||
config.put("sendClientIdOnLogout", Boolean.TRUE.toString());
|
||||
identityProviderResource.update(representation);
|
||||
logInAsUserInIDPForFirstTime();
|
||||
appPage.assertCurrent();
|
||||
executeLogoutFromRealm(
|
||||
getConsumerRoot(),
|
||||
bc.consumerRealmName(),
|
||||
"something-else",
|
||||
null,
|
||||
"broker-app",
|
||||
null
|
||||
);
|
||||
logoutConfirmPage.isCurrent();
|
||||
// confirm logout at consumer
|
||||
logoutConfirmPage.confirmLogout();
|
||||
// confirm logout at provider
|
||||
logoutConfirmPage.confirmLogout();
|
||||
|
||||
WaitUtils.waitForPageToLoad();
|
||||
logoutConfirmPage.isCurrent();
|
||||
Assert.assertTrue(driver.getPageSource().contains("You are logging out from following apps"));
|
||||
Assert.assertTrue(driver.getPageSource().contains("broker-app"));
|
||||
|
||||
oauth.clientId("account");
|
||||
oauth.redirectUri(getConsumerRoot() + "/auth/realms/" + REALM_PROV_NAME + "/account");
|
||||
loginPage.open(REALM_PROV_NAME);
|
||||
waitForPage(driver, "sign in to provider", true);
|
||||
} finally {
|
||||
representation.setConfig(originalConfig);
|
||||
identityProviderResource.update(representation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue