From fa383bf76ca3581f271653deccc159123bec00f3 Mon Sep 17 00:00:00 2001 From: Markus Till Date: Wed, 10 Aug 2022 18:25:50 +0200 Subject: [PATCH] Suppress confirmation screen for logout in oidc (#13471) Closes #13469 --- .../protocol/oidc/OIDCLoginProtocolFactory.java | 4 ++++ .../protocol/oidc/OIDCProviderConfig.java | 6 ++++++ .../protocol/oidc/endpoints/LogoutEndpoint.java | 2 +- .../testsuite/oauth/LegacyLogoutTest.java | 17 +++++++++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java index be7841cfe5..23a959e552 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java @@ -104,6 +104,7 @@ public class OIDCLoginProtocolFactory extends AbstractLoginProtocolFactory { public static final String ROLES_SCOPE_CONSENT_TEXT = "${rolesScopeConsentText}"; public static final String CONFIG_LEGACY_LOGOUT_REDIRECT_URI = "legacy-logout-redirect-uri"; + public static final String SUPPRESS_LOGOUT_CONFIRMATION_SCREEN = "suppress-logout-confirmation-screen"; private OIDCProviderConfig providerConfig; @@ -113,6 +114,9 @@ public class OIDCLoginProtocolFactory extends AbstractLoginProtocolFactory { if (providerConfig.isLegacyLogoutRedirectUri()) { logger.warnf("Deprecated switch '%s' is enabled. Please try to disable it and update your clients to use OpenID Connect compliant way for RP-initiated logout.", CONFIG_LEGACY_LOGOUT_REDIRECT_URI); } + if (providerConfig.suppressLogoutConfirmationScreen()) { + logger.warnf("Deprecated switch '%s' is enabled. Please try to disable it and update your clients to use OpenID Connect compliant way for RP-initiated logout.", SUPPRESS_LOGOUT_CONFIRMATION_SCREEN); + } } @Override diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCProviderConfig.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCProviderConfig.java index d450032c5f..b15cf42a37 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCProviderConfig.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCProviderConfig.java @@ -26,12 +26,18 @@ import org.keycloak.Config; public class OIDCProviderConfig { private final boolean legacyLogoutRedirectUri; + private final boolean suppressLogoutConfirmationScreen; public OIDCProviderConfig(Config.Scope config) { this.legacyLogoutRedirectUri = config.getBoolean(OIDCLoginProtocolFactory.CONFIG_LEGACY_LOGOUT_REDIRECT_URI, false); + this.suppressLogoutConfirmationScreen = config.getBoolean(OIDCLoginProtocolFactory.SUPPRESS_LOGOUT_CONFIRMATION_SCREEN, false); } public boolean isLegacyLogoutRedirectUri() { return legacyLogoutRedirectUri; } + + public boolean suppressLogoutConfirmationScreen() { + return suppressLogoutConfirmationScreen; + } } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java index 8c11866ff8..5bf5aa587e 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LogoutEndpoint.java @@ -313,7 +313,7 @@ public class LogoutEndpoint { } // Logout confirmation screen will be displayed to the user in this case - if (confirmationNeeded || forcedConfirmation) { + if ((confirmationNeeded || forcedConfirmation) && !providerConfig.suppressLogoutConfirmationScreen()) { return displayLogoutConfirmationScreen(loginForm, logoutSession); } else { return doBrowserLogout(logoutSession); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/LegacyLogoutTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/LegacyLogoutTest.java index 6a1533a417..a1044bcb79 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/LegacyLogoutTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/LegacyLogoutTest.java @@ -112,6 +112,7 @@ public class LegacyLogoutTest extends AbstractTestRealmKeycloakTest { @After public void revertConfiguration() { getTestingClient().testing().setSystemPropertyOnServer("oidc." + OIDCLoginProtocolFactory.CONFIG_LEGACY_LOGOUT_REDIRECT_URI, "false"); + getTestingClient().testing().setSystemPropertyOnServer("oidc." + OIDCLoginProtocolFactory.SUPPRESS_LOGOUT_CONFIRMATION_SCREEN, "false"); getTestingClient().testing().reinitializeProviderFactoryWithSystemPropertiesScope(LoginProtocol.class.getName(), OIDCLoginProtocol.LOGIN_PROTOCOL, "oidc."); } @@ -237,7 +238,23 @@ public class LegacyLogoutTest extends AbstractTestRealmKeycloakTest { MatcherAssert.assertThat(false, is(isSessionActive(sessionId))); assertCurrentUrlEquals(APP_REDIRECT_URI); } + } + // Test with "post_logout_redirect_uri" without "id_token_hint" and "suppress-logout-confirmation-screen": User should logout non interactive. + @Test + public void logoutWithPostLogoutUriWithoutIdTokenHintAndSuppressedConfirmation() { + getTestingClient().testing().setSystemPropertyOnServer("oidc." + OIDCLoginProtocolFactory.SUPPRESS_LOGOUT_CONFIRMATION_SCREEN, "true"); + getTestingClient().testing().reinitializeProviderFactoryWithSystemPropertiesScope(LoginProtocol.class.getName(), OIDCLoginProtocol.LOGIN_PROTOCOL, "oidc."); + + OAuthClient.AccessTokenResponse tokenResponse = loginUser(); + String sessionId = tokenResponse.getSessionState(); + + String logoutUrl = oauth.getLogoutUrl().postLogoutRedirectUri(APP_REDIRECT_URI).build(); + driver.navigate().to(logoutUrl); + + events.expectLogout(sessionId).detail(Details.REDIRECT_URI, APP_REDIRECT_URI).assertEvent(); + Assert.assertThat(false, is(isSessionActive(sessionId))); + assertCurrentUrlEquals(APP_REDIRECT_URI); } private OAuthClient.AccessTokenResponse loginUser() {