[java-identity-provider] branch main updated: IDP-2484 - Allow IdP role in metadata query endpoint

Codeberg noreply at shibboleth.net
Mon Oct 12 14:40:24 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/48bbf649a750ba8a9f833a2937594ac23f4bc8c5

The following commit(s) were added to refs/heads/main by this push:
     new 48bbf649a IDP-2484 - Allow IdP role in metadata query endpoint
48bbf649a is described below

commit 48bbf649a750ba8a9f833a2937594ac23f4bc8c5
Author: Scott Cantor <scott at restingparrotsoftware.com>
AuthorDate: Mon Oct 12 10:38:30 2026 -0400

    IDP-2484 - Allow IdP role in metadata query endpoint
    
    https://shibboleth.atlassian.net/browse/IDP-2484
    
    Added mutually exclusive idp and sp flag options, defaulting to sp.
---
 .../shibboleth/idp/cli/MetadataQueryArguments.java | 25 ++++++++++-
 .../idp/profile/impl/MetadataQueryRequest.java     | 27 +++++++++++
 .../profile/impl/MetadataQueryRequestDecoder.java  | 52 +++++++++++++++++++++-
 3 files changed, 102 insertions(+), 2 deletions(-)

diff --git a/idp-cli/src/main/java/net/shibboleth/idp/cli/MetadataQueryArguments.java b/idp-cli/src/main/java/net/shibboleth/idp/cli/MetadataQueryArguments.java
index e6110152e..896924584 100644
--- a/idp-cli/src/main/java/net/shibboleth/idp/cli/MetadataQueryArguments.java
+++ b/idp-cli/src/main/java/net/shibboleth/idp/cli/MetadataQueryArguments.java
@@ -29,7 +29,15 @@ public class MetadataQueryArguments extends AbstractCommandLineArguments {
     @Parameter(names = {"-e", "--entityID"}, required = true, description = "EntityID to find metadata for")
     @Nullable private String entityID;
 
-    /** Role protocol.  */
+    /** IdP role. */
+    @Parameter(names = {"--idp"}, description = "Query for Identity Provider role")
+    private boolean idp;
+
+    /** SP role. */
+    @Parameter(names = {"--sp"}, description = "Query for Service Provider role")
+    private boolean sp;
+    
+    /** Protocol.  */
     @Parameter(names = {"--protocol"}, description = "Optional protocol to find metadata role for")
     @Nullable private String protocol;
 
@@ -49,6 +57,11 @@ public class MetadataQueryArguments extends AbstractCommandLineArguments {
     /** {@inheritDoc} */
     @Override
     public void validate() {
+        
+        if (idp && sp) {
+            throw new IllegalArgumentException("The idp and sp role options are mutually exclusive");
+        }
+
         try {
             if (saml1) {
                 if (saml2 || cas || protocol != null) {
@@ -85,6 +98,15 @@ public class MetadataQueryArguments extends AbstractCommandLineArguments {
         
         try {
             builder.append("entityID=").append(URLEncoder.encode(entityID, "UTF-8"));
+            
+            // Role.
+            if (idp) {
+                builder.append("&idp=1");
+            } else if (sp) {
+                builder.append("&sp=1");
+            }
+            
+            // Protocol
             if (saml1) {
                 builder.append("&saml1");
             } else if (saml2) {
@@ -94,6 +116,7 @@ public class MetadataQueryArguments extends AbstractCommandLineArguments {
             } else if (protocol != null) {
                 builder.append("&protocol=").append(URLEncoder.encode(protocol, "UTF-8"));
             }
+            
         } catch (final UnsupportedEncodingException e) {
             // UTF-8 is a required encoding. 
         }
diff --git a/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/MetadataQueryRequest.java b/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/MetadataQueryRequest.java
index 0100699af..876be53ea 100644
--- a/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/MetadataQueryRequest.java
+++ b/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/MetadataQueryRequest.java
@@ -16,6 +16,7 @@ package net.shibboleth.idp.profile.impl;
 
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.ThreadSafe;
+import javax.xml.namespace.QName;
 
 import org.opensaml.saml.metadata.resolver.DetectDuplicateEntityIDs;
 
@@ -38,6 +39,9 @@ public class MetadataQueryRequest {
     /** Protocol identifier for query. */
     @Nullable private String protocol;
     
+    /** Metadata role for query. */
+    @Nullable private QName role;
+    
     /** The strategy for duplicate entityID detection. */
     @Nullable private DetectDuplicateEntityIDs detectDuplicateEntityIDs;
 
@@ -66,6 +70,28 @@ public class MetadataQueryRequest {
         entityID = StringSupport.trimOrNull(id);
     }
 
+    /**
+     * Get the role to query on.
+     * 
+     * @return role to query
+     * 
+     * @since 5.3.0
+     */
+    @Nullable public QName getRole() {
+        return role;
+    }
+    
+    /**
+     * Set the role to query on.
+     * 
+     * @param qname role for query
+     * 
+     * @since 5.3.0
+     */
+    public void setRole(@Nullable final QName qname) {
+        role = qname;
+    }
+    
     /**
      * Get the protocol to query on.
      * 
@@ -107,6 +133,7 @@ public class MetadataQueryRequest {
     public String toString() {
         return MoreObjects.toStringHelper(this)
             .add("entityID", entityID)
+            .add("role", role)
             .add("protocol", protocol)
             .add("detectDuplicateEntityIDs", detectDuplicateEntityIDs)
             .toString();
diff --git a/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/MetadataQueryRequestDecoder.java b/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/MetadataQueryRequestDecoder.java
index 045232007..6d0a5c4cb 100644
--- a/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/MetadataQueryRequestDecoder.java
+++ b/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/impl/MetadataQueryRequestDecoder.java
@@ -16,7 +16,9 @@ package net.shibboleth.idp.profile.impl;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
+import javax.xml.namespace.QName;
 
+import org.opensaml.core.xml.schema.XSBooleanValue;
 import org.opensaml.messaging.context.MessageContext;
 import org.opensaml.messaging.decoder.MessageDecodingException;
 import org.opensaml.messaging.decoder.servlet.AbstractHttpServletRequestMessageDecoder;
@@ -25,6 +27,7 @@ import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext;
 import org.opensaml.saml.common.messaging.context.SAMLProtocolContext;
 import org.opensaml.saml.common.xml.SAMLConstants;
 import org.opensaml.saml.metadata.resolver.DetectDuplicateEntityIDs;
+import org.opensaml.saml.saml2.metadata.IDPSSODescriptor;
 import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
 
 import jakarta.servlet.http.HttpServletRequest;
@@ -39,6 +42,20 @@ public class MetadataQueryRequestDecoder extends AbstractHttpServletRequestMessa
     /** Name of the query parameter carrying the entityID: {@value} . */
     @Nonnull @NotEmpty public static final String ENTITY_ID_PARAM = "entityID";
 
+    /**
+     * Name of the query parameter indicating the IdP role: {@value} .
+     * 
+     * @since 5.3.0
+     */
+    @Nonnull @NotEmpty public static final String IDP_PARAM = "idp";
+
+    /**
+     * Name of the query parameter indicating the SP role: {@value} .
+     * 
+     * @since 5.3.0
+     */
+    @Nonnull @NotEmpty public static final String SP_PARAM = "sp";
+    
     /** Name of the query parameter carrying the protocol: {@value} . */
     @Nonnull @NotEmpty public static final String PROTOCOL_PARAM = "protocol";
 
@@ -78,7 +95,7 @@ public class MetadataQueryRequestDecoder extends AbstractHttpServletRequestMessa
         setMessageContext(messageContext);
         
         final SAMLPeerEntityContext peerCtx = new SAMLPeerEntityContext();
-        peerCtx.setRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
+        peerCtx.setRole(getRole(request));
         peerCtx.setEntityId(message.getEntityID());
         messageContext.addSubcontext(peerCtx, true);
         
@@ -110,6 +127,39 @@ public class MetadataQueryRequestDecoder extends AbstractHttpServletRequestMessa
         }
         return name;
     }
+    
+    /**
+     * Get the role.
+     * 
+     * @param request current HTTP request
+     * 
+     * @return role identifier
+     * 
+     * @throws MessageDecodingException
+     * 
+     * @since 5.3.0
+     */
+    @Nonnull protected QName getRole(@Nonnull final HttpServletRequest request) throws MessageDecodingException {
+        final String idp = StringSupport.trimOrNull(request.getParameter(IDP_PARAM));
+        final String sp = StringSupport.trimOrNull(request.getParameter(SP_PARAM));
+        
+        final XSBooleanValue idpflag = XSBooleanValue.valueOf(idp != null ? idp : "0");
+        final XSBooleanValue spflag = XSBooleanValue.valueOf(sp != null ? sp : "0");
+        
+        final Boolean idpfinal = idpflag.getValue();
+        final Boolean spfinal = spflag.getValue();
+        
+        if (idpfinal != null && idpfinal && spfinal != null && spfinal) {
+            throw new MessageDecodingException("Both IdP and SP roles specified.");
+        }
+        
+        if (idpfinal != null && idpfinal) {
+            return IDPSSODescriptor.DEFAULT_ELEMENT_NAME;
+        } else {
+            // Default or if set explicitly.
+            return SPSSODescriptor.DEFAULT_ELEMENT_NAME;
+        }
+    }
 
     /**
      * Get the protocol.

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


More information about the commits mailing list