successful SAML IdP Logout Request with BaseID or EncryptedID and SessionIndex

Closes #23528

Signed-off-by: cgeorgilakis-grnet <cgeorgilakis@admin.grnet.gr>
This commit is contained in:
cgeorgilakis-grnet 2023-09-26 10:10:50 +03:00 committed by Pedro Igor
parent d61b1ddb09
commit 24f105e8fc
4 changed files with 27 additions and 1 deletions

View file

@ -329,8 +329,20 @@ public class SAMLEndpoint {
} }
protected Response logoutRequest(LogoutRequestType request, String relayState) { 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.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<LogoutRequestType> ref = new AtomicReference<>(request); AtomicReference<LogoutRequestType> ref = new AtomicReference<>(request);
session.sessions().getUserSessionByBrokerUserIdStream(realm, brokerUserId) session.sessions().getUserSessionByBrokerUserIdStream(realm, brokerUserId)
.filter(userSession -> userSession.getState() != UserSessionModel.State.LOGGING_OUT && .filter(userSession -> userSession.getState() != UserSessionModel.State.LOGGING_OUT &&

View file

@ -248,6 +248,8 @@ public class Messages {
public static final String IDENTITY_PROVIDER_LOGIN_FAILURE = "identityProviderLoginFailure"; 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 INSUFFICIENT_LEVEL_OF_AUTHENTICATION = "insufficientLevelOfAuthentication";
public static final String SUCCESS_LOGOUT = "successLogout"; public static final String SUCCESS_LOGOUT = "successLogout";

View file

@ -16,6 +16,7 @@
*/ */
package org.keycloak.testsuite.util.saml; package org.keycloak.testsuite.util.saml;
import org.keycloak.dom.saml.v2.assertion.BaseIDAbstractType;
import org.keycloak.testsuite.util.SamlClientBuilder; import org.keycloak.testsuite.util.SamlClientBuilder;
import org.keycloak.dom.saml.v2.assertion.NameIDType; import org.keycloak.dom.saml.v2.assertion.NameIDType;
import org.keycloak.dom.saml.v2.protocol.LogoutRequestType; import org.keycloak.dom.saml.v2.protocol.LogoutRequestType;
@ -41,6 +42,7 @@ public class CreateLogoutRequestStepBuilder extends SamlDocumentStepBuilder<Logo
private Supplier<String> sessionIndex = () -> null; private Supplier<String> sessionIndex = () -> null;
private Supplier<NameIDType> nameId = () -> null; private Supplier<NameIDType> nameId = () -> null;
private Supplier<BaseIDAbstractType> baseId = () -> null;
private Supplier<String> relayState = () -> null; private Supplier<String> relayState = () -> null;
private String signingPublicKeyPem; // TODO: should not be needed private String signingPublicKeyPem; // TODO: should not be needed
private String signingPrivateKeyPem; private String signingPrivateKeyPem;
@ -95,6 +97,10 @@ public class CreateLogoutRequestStepBuilder extends SamlDocumentStepBuilder<Logo
return nameId.get(); return nameId.get();
} }
public BaseIDAbstractType baseId() {
return baseId.get();
}
public CreateLogoutRequestStepBuilder nameId(NameIDType nameId) { public CreateLogoutRequestStepBuilder nameId(NameIDType nameId) {
this.nameId = () -> nameId; this.nameId = () -> nameId;
return this; return this;
@ -105,6 +111,11 @@ public class CreateLogoutRequestStepBuilder extends SamlDocumentStepBuilder<Logo
return this; return this;
} }
public CreateLogoutRequestStepBuilder baseId(Supplier<BaseIDAbstractType> baseId) {
this.baseId = baseId;
return this;
}
public CreateLogoutRequestStepBuilder signWith(String signingPrivateKeyPem, String signingPublicKeyPem) { public CreateLogoutRequestStepBuilder signWith(String signingPrivateKeyPem, String signingPublicKeyPem) {
return signWith(signingPrivateKeyPem, signingPublicKeyPem, null); return signWith(signingPrivateKeyPem, signingPublicKeyPem, null);
} }

View file

@ -225,6 +225,7 @@ expiredActionMessage=Action expired. Please continue with login now.
expiredActionTokenNoSessionMessage=Action expired. expiredActionTokenNoSessionMessage=Action expired.
expiredActionTokenSessionExistsMessage=Action expired. Please start again. expiredActionTokenSessionExistsMessage=Action expired. Please start again.
sessionLimitExceeded=There are too many sessions sessionLimitExceeded=There are too many sessions
identityProviderLogoutFailure=SAML IdP Logout Failure
missingFirstNameMessage=Please specify first name. missingFirstNameMessage=Please specify first name.
missingLastNameMessage=Please specify last name. missingLastNameMessage=Please specify last name.