From 281a7ed1c82d92bbf09c18ca1bbdff19d1bc0e05 Mon Sep 17 00:00:00 2001
From: Mateusz Małek <ieg3lwut8aippmr7tzhqyznn@noreply.damisa.net>
Date: Tue, 08 Nov 2022 09:07:44 +0000
Subject: [PATCH] Match Apereo CAS behavior with regard to single log-out

---
 src/test/java/org/keycloak/protocol/cas/LogoutHelperTest.java   |   12 +++++++++++-
 src/main/java/org/keycloak/protocol/cas/utils/LogoutHelper.java |   11 +++++++++--
 src/main/java/org/keycloak/protocol/cas/CASLoginProtocol.java   |    2 +-
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/src/main/java/org/keycloak/protocol/cas/CASLoginProtocol.java b/src/main/java/org/keycloak/protocol/cas/CASLoginProtocol.java
index 7eb67fc..d8b7a86 100644
--- a/src/main/java/org/keycloak/protocol/cas/CASLoginProtocol.java
+++ b/src/main/java/org/keycloak/protocol/cas/CASLoginProtocol.java
@@ -143,8 +143,8 @@
     }
 
     private void sendSingleLogoutRequest(String logoutUrl, String serviceTicket) {
-        HttpEntity requestEntity = LogoutHelper.buildSingleLogoutRequest(serviceTicket);
         try {
+            HttpEntity requestEntity = LogoutHelper.buildSingleLogoutRequest(serviceTicket);
             LogoutHelper.postWithRedirect(session, logoutUrl, requestEntity);
             logger.debug("Sent CAS single logout for service " + logoutUrl);
         } catch (IOException e) {
diff --git a/src/main/java/org/keycloak/protocol/cas/utils/LogoutHelper.java b/src/main/java/org/keycloak/protocol/cas/utils/LogoutHelper.java
index ec365cd..5e26e8d 100644
--- a/src/main/java/org/keycloak/protocol/cas/utils/LogoutHelper.java
+++ b/src/main/java/org/keycloak/protocol/cas/utils/LogoutHelper.java
@@ -2,8 +2,11 @@
 
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
 import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpPost;
+import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.entity.ContentType;
 import org.apache.http.entity.StringEntity;
 import org.keycloak.connections.httpclient.HttpClientProvider;
@@ -16,6 +19,8 @@
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.UUID;
+import java.util.LinkedList;
+import java.util.List;
 
 public class LogoutHelper {
     //although it looks alike, the CAS SLO protocol has nothing to do with SAML; so we build the format
@@ -25,12 +30,14 @@
             "  <samlp:SessionIndex>$SESSION_IDENTIFIER</samlp:SessionIndex>\n" +
             "</samlp:LogoutRequest>";
 
-    public static HttpEntity buildSingleLogoutRequest(String serviceTicket) {
+    public static HttpEntity buildSingleLogoutRequest(String serviceTicket) throws IOException {
         String id = "ID_" + UUID.randomUUID().toString();
         String issueInstant = new SimpleDateFormat("yyyy-MM-dd'T'H:mm:ss").format(new Date());
         String document = TEMPLATE.replace("$ID", id).replace("$ISSUE_INSTANT", issueInstant)
                 .replace("$SESSION_IDENTIFIER", serviceTicket);
-        return new StringEntity(document, ContentType.APPLICATION_XML.withCharset(StandardCharsets.UTF_8));
+        List<NameValuePair> parameters = new LinkedList<>();
+        parameters.add(new BasicNameValuePair("logoutRequest", document));
+        return new UrlEncodedFormEntity(parameters);
     }
 
     public static void postWithRedirect(KeycloakSession session, String url, HttpEntity postBody) throws IOException {
diff --git a/src/test/java/org/keycloak/protocol/cas/LogoutHelperTest.java b/src/test/java/org/keycloak/protocol/cas/LogoutHelperTest.java
index 76169df..b8b6a40 100644
--- a/src/test/java/org/keycloak/protocol/cas/LogoutHelperTest.java
+++ b/src/test/java/org/keycloak/protocol/cas/LogoutHelperTest.java
@@ -1,12 +1,17 @@
 package org.keycloak.protocol.cas;
 
 import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.utils.URLEncodedUtils;
 import org.junit.Test;
 import org.keycloak.protocol.cas.utils.LogoutHelper;
 import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
 import org.keycloak.saml.common.util.DocumentUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
+
+import java.util.List;
+import java.util.stream.Collectors;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -15,7 +20,12 @@
     @Test
     public void testLogoutRequest() throws Exception {
         HttpEntity requestEntity = LogoutHelper.buildSingleLogoutRequest("ST-test");
-        Document doc = DocumentUtil.getDocument(requestEntity.getContent());
+
+        List<NameValuePair> parameters = URLEncodedUtils.parse(requestEntity).stream().filter(parameter -> "logoutRequest".equals(parameter.getName())).collect(Collectors.toList());
+        assertEquals(1, parameters.size());
+
+        String logoutRequest = parameters.get(0).getValue();
+        Document doc = DocumentUtil.getDocument(logoutRequest);
 
         assertEquals("LogoutRequest", doc.getDocumentElement().getLocalName());
         assertEquals(JBossSAMLURIConstants.PROTOCOL_NSURI.get(), doc.getDocumentElement().getNamespaceURI());

--
Gitblit v1.9.1