[java-identity-provider] 02/02: IDP-2422 - CAS DefaultServiceComparator is case insensitive

Codeberg noreply at shibboleth.net
Thu Jan 8 17:40:59 UTC 2026


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch main
in repository java-identity-provider.

View the commit online:
https://codeberg.org/Shibboleth/java-identity-provider/commit/f03d09914b2ed417fdca27490e66a8e0ada44a58

commit f03d09914b2ed417fdca27490e66a8e0ada44a58
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Jan 8 12:40:46 2026 -0500

    IDP-2422 - CAS DefaultServiceComparator is case insensitive
    
    https://shibboleth.atlassian.net/browse/IDP-2422
    
    Add flag to allow existing comparator to toggled to case-sensitive.
    Not changing default for now.
---
 .../idp/cas/protocol/ServiceTicketResponse.java    |  3 +++
 .../idp/cas/service/DefaultServiceComparator.java  | 28 +++++++++++++++++++---
 .../shibboleth/idp/conf/cas-protocol-system.xml    |  3 ++-
 3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/protocol/ServiceTicketResponse.java b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/protocol/ServiceTicketResponse.java
index 23dcc00cf..31445cf26 100644
--- a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/protocol/ServiceTicketResponse.java
+++ b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/protocol/ServiceTicketResponse.java
@@ -108,6 +108,9 @@ public class ServiceTicketResponse {
         // TODO: Get this call out of here, Spring has patched it 3 times and counting.
         // If the original call doesn't even check for duplicate parameter names in the original URL
         // I doubt this is even bulletproof, though I don't know the CAS spec enough to say.
+        // What I do know now is that we can't replace this unless we ensure the addition of the
+        // ticket parameter does not require re-encoding the existing values as CAS protocol
+        // depends on that not being changed by the IdP. This is horrendous, but is simply how it works.
         final UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(serviceURL);
         builder.queryParam(getTicketParameterName(), serviceTicket);
         return builder.build().toUriString();
diff --git a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/service/DefaultServiceComparator.java b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/service/DefaultServiceComparator.java
index bd33198db..890250207 100644
--- a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/service/DefaultServiceComparator.java
+++ b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/service/DefaultServiceComparator.java
@@ -28,8 +28,11 @@ import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
- * Default comparator implementation for comparing CAS service URLs. URL comparison is case-insensitive and supports
- * ignoring predefined URL path parameters. The common session marker <em>;jessionid=value</em> is ignored by default.
+ * Default comparator implementation for comparing CAS service URLs. URL comparison is case-insensitive by default
+ * and supports ignoring predefined URL path parameters. The common session marker <em>;jessionid=value</em> is
+ * ignored by default.
+ * 
+ * <p>A future version MAY change the default to case-sensitive.</p>
  *
  * @author Marvin S. Addison
  */
@@ -41,6 +44,9 @@ public class DefaultServiceComparator implements Comparator<String> {
     /** Ignored patterns in path part of URL. */
     @Nonnull private final Pattern[] ignoredPatterns;
 
+    /**  Whether the check should be case-sensitive. */
+    private boolean caseSensitive;
+    
     /** Creates a new instance that ignores <em>;jsessionid=value</em>. */
     public DefaultServiceComparator() {
         this("jsessionid");
@@ -58,6 +64,17 @@ public class DefaultServiceComparator implements Comparator<String> {
             ignoredPatterns[i] = Pattern.compile(";" + parameterNames[i] + "(?:=[^;/]+)?", Pattern.CASE_INSENSITIVE);
         }
     }
+    
+    /**
+     * Sets whether the eventual comparison is case-sensitive.
+     * 
+     * <p>Defaults to false.</p>
+     * 
+     * @param flag
+     */
+    public void setCaseSensitive(final boolean flag) {
+        caseSensitive = flag;
+    }
 
     /** {@inheritDoc} */
     public int compare(final String a, final String b) {
@@ -70,7 +87,12 @@ public class DefaultServiceComparator implements Comparator<String> {
                 return 1;
             }
         }
-        return stripPathParameters(a).compareToIgnoreCase(stripPathParameters(b));
+        
+        if (caseSensitive) {
+            return stripPathParameters(a).compareTo(stripPathParameters(b));
+        } else {
+            return stripPathParameters(a).compareToIgnoreCase(stripPathParameters(b));
+        }
     }
 
     /**
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/cas-protocol-system.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/cas-protocol-system.xml
index d43ff8320..2b6b32c0e 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/cas-protocol-system.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/cas-protocol-system.xml
@@ -66,7 +66,8 @@
     <bean id="shibboleth.DefaultCASProxyValidateIdPSessionPredicate" parent="shibboleth.Conditions.FALSE" />
 
     <bean id="shibboleth.DefaultCASServiceComparator"
-          class="net.shibboleth.idp.cas.service.DefaultServiceComparator" />
+          class="net.shibboleth.idp.cas.service.DefaultServiceComparator"
+          p:caseSensitive="%{idp.cas.caseSensitiveComparator:false}" />
 
     <util:list id="shibboleth.DefaultCASServiceRegistries">
         <ref bean="shibboleth.CASMetadataServiceRegistry" />

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list