From 24f105e8fce51dae1c7996b912a265fcd6bb7bde Mon Sep 17 00:00:00 2001 From: cgeorgilakis-grnet Date: Tue, 26 Sep 2023 10:10:50 +0300 Subject: [PATCH] successful SAML IdP Logout Request with BaseID or EncryptedID and SessionIndex Closes #23528 Signed-off-by: cgeorgilakis-grnet --- .../org/keycloak/broker/saml/SAMLEndpoint.java | 14 +++++++++++++- .../org/keycloak/services/messages/Messages.java | 2 ++ .../util/saml/CreateLogoutRequestStepBuilder.java | 11 +++++++++++ .../base/login/messages/messages_en.properties | 1 + 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/services/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java b/services/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java index a36ca52374..a54754aefb 100755 --- a/services/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java +++ b/services/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java @@ -329,8 +329,20 @@ public class SAMLEndpoint { } protected Response logoutRequest(LogoutRequestType request, String relayState) { - String brokerUserId = config.getAlias() + "." + request.getNameID().getValue(); + if (request.getNameID() == null && request.getBaseID() == null && request.getEncryptedID() == null){ + logger.error("SAML IdP Logout request must contain at least one of BaseID, NameID and EncryptedID"); + event.error(Errors.INVALID_SAML_LOGOUT_REQUEST); + return ErrorPage.error(session, null, Response.Status.BAD_REQUEST, Messages.IDENTITY_PROVIDER_LOGOUT_FAILURE); + } + if (request.getSessionIndex() == null || request.getSessionIndex().isEmpty()) { + if (request.getNameID() == null){ + //TODO this need to be implemented + logger.error("SAML IdP Logout request contains BaseID or EncryptedID without Session Index"); + event.error(Errors.INVALID_SAML_LOGOUT_REQUEST); + return ErrorPage.error(session, null, Response.Status.NOT_IMPLEMENTED, Messages.IDENTITY_PROVIDER_LOGOUT_FAILURE); + } + String brokerUserId = config.getAlias() + "." + request.getNameID().getValue(); AtomicReference ref = new AtomicReference<>(request); session.sessions().getUserSessionByBrokerUserIdStream(realm, brokerUserId) .filter(userSession -> userSession.getState() != UserSessionModel.State.LOGGING_OUT && diff --git a/services/src/main/java/org/keycloak/services/messages/Messages.java b/services/src/main/java/org/keycloak/services/messages/Messages.java index 8daf8bdb03..e967756f71 100755 --- a/services/src/main/java/org/keycloak/services/messages/Messages.java +++ b/services/src/main/java/org/keycloak/services/messages/Messages.java @@ -248,6 +248,8 @@ public class Messages { public static final String IDENTITY_PROVIDER_LOGIN_FAILURE = "identityProviderLoginFailure"; + public static final String IDENTITY_PROVIDER_LOGOUT_FAILURE = "identityProviderLogoutFailure"; + public static final String INSUFFICIENT_LEVEL_OF_AUTHENTICATION = "insufficientLevelOfAuthentication"; public static final String SUCCESS_LOGOUT = "successLogout"; diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/saml/CreateLogoutRequestStepBuilder.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/saml/CreateLogoutRequestStepBuilder.java index 609a6e2c38..09245ff2c2 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/saml/CreateLogoutRequestStepBuilder.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/saml/CreateLogoutRequestStepBuilder.java @@ -16,6 +16,7 @@ */ package org.keycloak.testsuite.util.saml; +import org.keycloak.dom.saml.v2.assertion.BaseIDAbstractType; import org.keycloak.testsuite.util.SamlClientBuilder; import org.keycloak.dom.saml.v2.assertion.NameIDType; import org.keycloak.dom.saml.v2.protocol.LogoutRequestType; @@ -41,6 +42,7 @@ public class CreateLogoutRequestStepBuilder extends SamlDocumentStepBuilder sessionIndex = () -> null; private Supplier nameId = () -> null; + private Supplier baseId = () -> null; private Supplier relayState = () -> null; private String signingPublicKeyPem; // TODO: should not be needed private String signingPrivateKeyPem; @@ -95,6 +97,10 @@ public class CreateLogoutRequestStepBuilder extends SamlDocumentStepBuilder nameId; return this; @@ -105,6 +111,11 @@ public class CreateLogoutRequestStepBuilder extends SamlDocumentStepBuilder baseId) { + this.baseId = baseId; + return this; + } + public CreateLogoutRequestStepBuilder signWith(String signingPrivateKeyPem, String signingPublicKeyPem) { return signWith(signingPrivateKeyPem, signingPublicKeyPem, null); } diff --git a/themes/src/main/resources/theme/base/login/messages/messages_en.properties b/themes/src/main/resources/theme/base/login/messages/messages_en.properties index caf3c014f4..80c4febe16 100755 --- a/themes/src/main/resources/theme/base/login/messages/messages_en.properties +++ b/themes/src/main/resources/theme/base/login/messages/messages_en.properties @@ -225,6 +225,7 @@ expiredActionMessage=Action expired. Please continue with login now. expiredActionTokenNoSessionMessage=Action expired. expiredActionTokenSessionExistsMessage=Action expired. Please start again. sessionLimitExceeded=There are too many sessions +identityProviderLogoutFailure=SAML IdP Logout Failure missingFirstNameMessage=Please specify first name. missingLastNameMessage=Please specify last name.