From 3db6a326bff257ac7cec00a886c3bde7426b63fa Mon Sep 17 00:00:00 2001
From: Charley Wu <akunzai@gmail.com>
Date: Wed, 26 Aug 2026 11:32:29 +0000
Subject: [PATCH] Add unit tests for CAS RedirectUtils
---
src/test/java/org/keycloak/protocol/cas/RedirectUtilsTest.java | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 164 insertions(+), 0 deletions(-)
diff --git a/src/test/java/org/keycloak/protocol/cas/RedirectUtilsTest.java b/src/test/java/org/keycloak/protocol/cas/RedirectUtilsTest.java
new file mode 100644
index 0000000..5ebb698
--- /dev/null
+++ b/src/test/java/org/keycloak/protocol/cas/RedirectUtilsTest.java
@@ -0,0 +1,164 @@
+package org.keycloak.protocol.cas;
+
+import org.junit.jupiter.api.Test;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakContext;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakUriInfo;
+import org.keycloak.protocol.cas.utils.RedirectUtils;
+
+import java.net.URI;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class RedirectUtilsTest {
+
+ private KeycloakSession createMockSession() {
+ KeycloakSession session = mock(KeycloakSession.class);
+ KeycloakContext context = mock(KeycloakContext.class);
+ KeycloakUriInfo uriInfo = mock(KeycloakUriInfo.class);
+ when(session.getContext()).thenReturn(context);
+ when(context.getUri()).thenReturn(uriInfo);
+ when(uriInfo.getBaseUri()).thenReturn(URI.create("http://localhost:8080/auth/"));
+ return session;
+ }
+
+ private ClientModel createMockClient(String... redirectUris) {
+ ClientModel client = mock(ClientModel.class);
+ when(client.getRedirectUris()).thenReturn(Set.of(redirectUris));
+ return client;
+ }
+
+ @Test
+ public void testVerifyRedirectUriNull() {
+ KeycloakSession session = createMockSession();
+ ClientModel client = mock(ClientModel.class);
+ assertNull(RedirectUtils.verifyRedirectUri(session, null, client));
+ assertNull(RedirectUtils.verifyRedirectUri(session, "https://localhost:5003/signin-cas", null));
+ assertNull(RedirectUtils.verifyRedirectUri(session, null, null));
+ }
+
+ @Test
+ public void testVerifyRedirectUriWithoutForbiddenParams() {
+ KeycloakSession session = createMockSession();
+ ClientModel client = createMockClient("https://localhost:5003/*");
+
+ String serviceUrl = "https://localhost:5003/signin-cas";
+ String verified = RedirectUtils.verifyRedirectUri(session, serviceUrl, client);
+
+ assertEquals(serviceUrl, verified);
+ }
+
+ @Test
+ public void testVerifyRedirectUriWithState() {
+ KeycloakSession session = createMockSession();
+ ClientModel client = createMockClient("https://localhost:5003/*");
+
+ String serviceUrl = "https://localhost:5003/signin-cas?state=CfDJ81234567890";
+ String verified = RedirectUtils.verifyRedirectUri(session, serviceUrl, client);
+
+ assertEquals(serviceUrl, verified);
+ }
+
+ @Test
+ public void testVerifyRedirectUriWithAllowedQueryParams() {
+ KeycloakSession session = createMockSession();
+ ClientModel client = createMockClient("https://localhost:5003/*");
+
+ String[] allowedParams = new String[]{"code", "id_token", "access_token", "session_state", "error", "custom_param"};
+ for (String param : allowedParams) {
+ String serviceUrl = "https://localhost:5003/signin-cas?" + param + "=testValue";
+ String verified = RedirectUtils.verifyRedirectUri(session, serviceUrl, client);
+ assertEquals(serviceUrl, verified, "Should be allowed for parameter: " + param);
+ }
+ }
+
+ @Test
+ public void testVerifyRedirectUriWithEncodedChars() {
+ KeycloakSession session = createMockSession();
+ ClientModel client = createMockClient("https://localhost:5003/*");
+
+ String serviceUrl = "https://localhost:5003/signin-cas?state=CfDJ8%20123";
+ String verified = RedirectUtils.verifyRedirectUri(session, serviceUrl, client);
+
+ assertEquals(serviceUrl, verified);
+ }
+
+ @Test
+ public void testVerifyRedirectUriWithForbiddenCasParams() {
+ KeycloakSession session = createMockSession();
+ ClientModel client = createMockClient("https://localhost:5003/*");
+
+ String[] forbiddenParams = new String[]{"ticket", "TICKET", "Ticket", "SAMLart", "samlart", "SAMLART"};
+ for (String param : forbiddenParams) {
+ String serviceUrl = "https://localhost:5003/signin-cas?" + param + "=ST-123456";
+ String verified = RedirectUtils.verifyRedirectUri(session, serviceUrl, client);
+ assertNull(verified, "Should be rejected for parameter: " + param);
+ }
+ }
+
+ @Test
+ public void testVerifyRedirectUriWithStateAndForbiddenCasParam() {
+ KeycloakSession session = createMockSession();
+ ClientModel client = createMockClient("https://localhost:5003/*");
+
+ String serviceUrl = "https://localhost:5003/signin-cas?state=CfDJ8&ticket=ST-123456";
+ String verified = RedirectUtils.verifyRedirectUri(session, serviceUrl, client);
+
+ assertNull(verified);
+
+ String samlUrl = "https://localhost:5003/signin-cas?state=CfDJ8&SAMLart=ST-123456";
+ String samlVerified = RedirectUtils.verifyRedirectUri(session, samlUrl, client);
+
+ assertNull(samlVerified);
+ }
+
+ @Test
+ public void testVerifyRedirectUriWithStateAndCustomParam() {
+ KeycloakSession session = createMockSession();
+ ClientModel client = createMockClient("https://localhost:5003/*");
+
+ String serviceUrl = "https://localhost:5003/signin-cas?state=CfDJ8&custom_param=value123";
+ String verified = RedirectUtils.verifyRedirectUri(session, serviceUrl, client);
+
+ assertEquals(serviceUrl, verified);
+ }
+
+ @Test
+ public void testVerifyRedirectUriWithFragment() {
+ KeycloakSession session = createMockSession();
+ ClientModel client = createMockClient("https://localhost:5003/*");
+
+ String serviceUrl = "https://localhost:5003/signin-cas?state=CfDJ8#section1";
+ String verified = RedirectUtils.verifyRedirectUri(session, serviceUrl, client);
+
+ assertEquals(serviceUrl, verified);
+ }
+
+ @Test
+ public void testVerifyRedirectUriInvalidDomain() {
+ KeycloakSession session = createMockSession();
+ ClientModel client = createMockClient("https://localhost:5003/*");
+
+ String serviceUrl = "https://evil.com/signin-cas?state=CfDJ8";
+ String verified = RedirectUtils.verifyRedirectUri(session, serviceUrl, client);
+
+ assertNull(verified);
+ }
+
+ @Test
+ public void testVerifyRedirectUriWithoutRequireRedirectUri() {
+ KeycloakSession session = createMockSession();
+ ClientModel singleRedirectClient = createMockClient("https://localhost:5003/*");
+
+ String verified = RedirectUtils.verifyRedirectUri(session, null, singleRedirectClient, false);
+ assertEquals("https://localhost:5003", verified);
+
+ ClientModel multiRedirectClient = createMockClient("https://localhost:5003/*", "https://localhost:5004/*");
+ assertNull(RedirectUtils.verifyRedirectUri(session, null, multiRedirectClient, false));
+ }
+}
--
Gitblit v1.10.0