[java-idp-plugin-metadatagen] branch dev/JMETAGEN-5 updated: JMETAGEN-5 - Generalize metadata generation

Scott Cantor cantor.2 at osu.edu
Tue Jul 11 20:01:08 UTC 2023


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

scantor pushed a commit to branch dev/JMETAGEN-5
in repository java-idp-plugin-metadatagen.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-metadatagen.git;a=commit;h=d087d3968278c3e1105058cafe88c08ed7f9595c

The following commit(s) were added to refs/heads/dev/JMETAGEN-5 by this push:
     new d087d39  JMETAGEN-5 - Generalize metadata generation
d087d39 is described below

commit d087d3968278c3e1105058cafe88c08ed7f9595c
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Jul 11 16:01:05 2023 -0400

    JMETAGEN-5 - Generalize metadata generation
    
    https://shibboleth.atlassian.net/browse/JMETAGEN-5
    
    Org, flag, and NameID format support.
    Cache roles for performance.
    Add OIDC endpoint support.
---
 .../impl/AssertionConsumerServiceConverter.java    |   9 ++
 .../impl/MetadataGenCommandLineArguments.java      | 142 +++++++++++++++------
 .../plugin/metadatagen/impl/MetadataGenTest.java   |   9 +-
 3 files changed, 122 insertions(+), 38 deletions(-)

diff --git a/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/AssertionConsumerServiceConverter.java b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/AssertionConsumerServiceConverter.java
index 087f059..3230dd6 100644
--- a/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/AssertionConsumerServiceConverter.java
+++ b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/AssertionConsumerServiceConverter.java
@@ -26,6 +26,7 @@ import org.opensaml.saml.saml2.metadata.AssertionConsumerService;
 
 import net.shibboleth.idp.cas.config.AbstractProtocolConfiguration;
 import net.shibboleth.shared.annotation.constraint.Live;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.collection.Pair;
 
 /**
@@ -33,6 +34,12 @@ import net.shibboleth.shared.collection.Pair;
  */
 public class AssertionConsumerServiceConverter extends org.opensaml.saml.metadata.generator.impl.AssertionConsumerServiceConverter {
     
+    /** Our profile-defined value for OpenID protocol support. */
+    @Nonnull @NotEmpty public static String OPENID_PROTOCOL = "http://openid.net/specs/openid-connect-core-1_0.html";
+    
+    /** Our profile-defined value for the OpenID RP binding. */
+    @Nonnull @NotEmpty public static String OPENID_BINDING = "https://tools.ietf.org/html/rfc6749#section-3.1.2";
+    
     /** {@inheritDoc} */
     @Nonnull public AssertionConsumerService apply(@Nullable final String value,
             @Nullable @Live final List<String> protocols) {
@@ -48,6 +55,8 @@ public class AssertionConsumerServiceConverter extends org.opensaml.saml.metadat
         } else if (input.startsWith("CASProxy/")) {
             return new Pair<>(AbstractProtocolConfiguration.PROTOCOL_URI,
                     AbstractProtocolConfiguration.PROTOCOL_URI + "/proxy");
+        } else if (input.startsWith("OIDC/")) {
+            return new Pair<>(OPENID_PROTOCOL, OPENID_BINDING);
         }
         return super.getProtocolAndBinding(input);
     }
diff --git a/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenCommandLineArguments.java b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenCommandLineArguments.java
index c9a216c..0e87942 100644
--- a/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenCommandLineArguments.java
+++ b/metadatagen-impl/src/main/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenCommandLineArguments.java
@@ -42,6 +42,7 @@ import org.opensaml.saml.saml2.metadata.AttributeAuthorityDescriptor;
 import org.opensaml.saml.saml2.metadata.Endpoint;
 import org.opensaml.saml.saml2.metadata.IDPSSODescriptor;
 import org.opensaml.saml.saml2.metadata.IndexedEndpoint;
+import org.opensaml.saml.saml2.metadata.NameIDFormat;
 import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
 import org.opensaml.security.x509.X509Support;
 import org.slf4j.Logger;
@@ -52,12 +53,12 @@ import com.google.common.base.Predicates;
 
 import net.shibboleth.idp.cli.AbstractIdPHomeAwareCommandLineArguments;
 import net.shibboleth.shared.annotation.constraint.Live;
-import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.annotation.constraint.NotLive;
 import net.shibboleth.shared.annotation.constraint.Unmodifiable;
 import net.shibboleth.shared.codec.Base64Support;
 import net.shibboleth.shared.codec.EncodingException;
 import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.primitive.StringSupport;
 
 /**
  * Command line arguments for Metadata Generation.
@@ -67,33 +68,18 @@ import net.shibboleth.shared.collection.CollectionSupport;
  */
 public class MetadataGenCommandLineArguments extends AbstractIdPHomeAwareCommandLineArguments
         implements TemplateMetadataGeneratorParameters {
-    
-    /** Property name for the back channel certificate. */
-    @Nonnull @NotEmpty public static final String BACKCHANNEL_PROPERTY = "idp.metadata.backchannel.cert";
-    
-    /** Property name for the back channel certificate. */
-    @Nonnull @NotEmpty public static final String DNS_NAME_PROPERTY = "idp.metadata.dnsname";
-
-    /** Property name for the MDUI languages. */
-    @Nonnull @NotEmpty public static final String MDUI_LANGS_PROPERTY = "idp.metadata.idpsso.mdui.langs";
-
-    /** Property prefix for DisplayName. */
-    @Nonnull @NotEmpty public static final String MDUI_DISPLAY_NAME_PREFIX = "idp.metadata.idpsso.mdui.displayname.";
-
-    /** Property prefix for Description. */
-    @Nonnull @NotEmpty public static final String MDUI_DESCRIPTION_PREFIX = "idp.metadata.idpsso.mdui.description.";
-
-    /** Property for logo y. */
-    @Nonnull @NotEmpty public static final String MDUI_LOGO_HEIGHT = "idp.metadata.idpsso.mdui.logo.height";
-
-    /** Property for logo x. */
-    @Nonnull @NotEmpty public static final String MDUI_LOGO_WIDTH = "idp.metadata.idpsso.mdui.logo.width";
-
-    /** Property for logo path. */
-    @Nonnull @NotEmpty public static final String MDUI_LOGO_PATH = "idp.metadata.idpsso.mdui.logo.path";
 
     /** Logger. */
     @Nullable private Logger log;
+    
+    /** Cached IdP role. */
+    @Nullable private IDPSSODescriptor idpRole;
+
+    /** Cached SP role. */
+    @Nullable private SPSSODescriptor spRole;
+
+    /** Cached AA role. */
+    @Nullable private AttributeAuthorityDescriptor aaRole;
 
     /** The unique ID. */
     @Parameter(names = {"--entityID", "--client_id", "--id"}, required=true, description="Unique ID for entity")
@@ -111,6 +97,13 @@ public class MetadataGenCommandLineArguments extends AbstractIdPHomeAwareCommand
     @Parameter(names = {"--aa"}, description="Include Attribute Authority role?")
     private boolean aa;
     
+    /** SP requires signed assertions?.*/
+    @Parameter(names = {"--want-assertions-signed", "-w"}, description="Require signed assertions?")
+    private boolean wantAssertionsSigned;
+
+    @Parameter(names = {"--nameid-format", "-f"}, description="SP NameID format(s)")
+    @Nonnull private List<String> nameIDFormats = new ArrayList<>();
+
     @Parameter(names = {"--sso"}, description="SingleSignOnService endpoint(s)")
     @Nonnull private List<String> ssoServices = new ArrayList<>();
 
@@ -138,29 +131,55 @@ public class MetadataGenCommandLineArguments extends AbstractIdPHomeAwareCommand
     @Parameter(names = {"--encryption", "-e"}, description="Path(s) to certificate(s) for encryption only")
     @Nonnull private List<String> encryptionPaths = new ArrayList<>();
 
+    @Parameter(names = {"--org-name", "-o"}, description="Organization name")
+    @Nullable private String orgName;
+
+    @Parameter(names = {"--org-url", "-u"}, description="Organization URL")
+    @Nullable private String orgURL;
+
     /** Omit namespaces from root element? */
     @Parameter(names = {"--omit-namespaces"}, description="Omit namespace declarations (assumes surrounding document context)")
     private boolean omitNamespaces;
     
     /** Output file path. */
-    @Parameter(names = {"--file", "-f"}, description="Path to output file (stdout otherwise)")
+    @Parameter(names = {"--file", "--out"}, description="Path to output file (stdout otherwise)")
     @Nullable private String outputFile;
 
-    /**
-     * Get the unique ID.
-     * 
-     * @return argument value
-     */
+    /** {@inheritDoc} */
     @Nullable public String getEntityID() {
         return entityID;
     }
     
+    /** {@inheritDoc} */
+    @Nullable public String getLang() {
+        if (getLanguageRanges().isEmpty()) {
+            return null;
+        }
+        return getLanguageRanges().get(0).getRange();
+    }
+    
+    /** {@inheritDoc} */
+    @Nullable public String getOrganizationName() {
+        return orgName;
+    }
+
+    /** {@inheritDoc} */
+    @Nullable public String getOrganizationURL() {
+        return orgURL;
+    }
+    
     /** {@inheritDoc} */
     @Nullable public SPSSODescriptor getSPSSODescriptor() {
         if (!sp) {
             return null;
         }
         
+        synchronized(this) {
+            if (spRole != null) {
+                return spRole;
+            }
+        }
+        
         final XMLObjectBuilderFactory bf = XMLObjectProviderRegistrySupport.getBuilderFactory();
         
         final SAMLObjectBuilder<SPSSODescriptor> builder =
@@ -188,7 +207,28 @@ public class MetadataGenCommandLineArguments extends AbstractIdPHomeAwareCommand
         }
         
         protocols.forEach(role::addSupportedProtocol);
+        
+        if (wantAssertionsSigned) {
+            role.setWantAssertionsSigned(wantAssertionsSigned);
+        }
+        
+        if (!nameIDFormats.isEmpty()) {
+            final SAMLObjectBuilder<NameIDFormat> formatBuilder =
+                    (SAMLObjectBuilder<NameIDFormat>) bf.<NameIDFormat>ensureBuilder(
+                            NameIDFormat.DEFAULT_ELEMENT_NAME);
+            
+            StringSupport.normalizeStringCollection(nameIDFormats).stream()
+                .forEach(format -> {
+                    final NameIDFormat obj = formatBuilder.buildObject();
+                    obj.setURI(format);
+                    role.getNameIDFormats().add(obj);
+                });
+        }
 
+        synchronized(this) {
+            spRole = role;
+        }
+        
         return role;
     }
 
@@ -198,6 +238,12 @@ public class MetadataGenCommandLineArguments extends AbstractIdPHomeAwareCommand
             return null;
         }
         
+        synchronized(this) {
+            if (idpRole != null) {
+                return idpRole;
+            }
+        }
+        
         final XMLObjectBuilderFactory bf = XMLObjectProviderRegistrySupport.getBuilderFactory();
 
         final SAMLObjectBuilder<IDPSSODescriptor> builder =
@@ -221,6 +267,10 @@ public class MetadataGenCommandLineArguments extends AbstractIdPHomeAwareCommand
         
         protocols.forEach(role::addSupportedProtocol);
 
+        synchronized(this) {
+            idpRole = role;
+        }
+        
         return role;
     }
 
@@ -229,6 +279,12 @@ public class MetadataGenCommandLineArguments extends AbstractIdPHomeAwareCommand
         if (!aa) {
             return null;
         }
+        
+        synchronized(this) {
+            if (aaRole != null) {
+                return aaRole;
+            }
+        }
 
         final XMLObjectBuilderFactory bf = XMLObjectProviderRegistrySupport.getBuilderFactory();
         
@@ -244,6 +300,10 @@ public class MetadataGenCommandLineArguments extends AbstractIdPHomeAwareCommand
         
         protocols.forEach(role::addSupportedProtocol);
         
+        synchronized(this) {
+            aaRole = role;
+        }
+        
         return role;
     }
     
@@ -296,7 +356,11 @@ public class MetadataGenCommandLineArguments extends AbstractIdPHomeAwareCommand
     
     /** {@inheritDoc} */
     @Nullable public Set<Namespace> getAdditionalNamespaces() {
-        return CollectionSupport.singleton(new Namespace("urn:mace:shibboleth:metadata:oidc:1.0", "oidcmd"));
+        final SPSSODescriptor role = getSPSSODescriptor();
+        if (role != null && role.isSupportedProtocol(AssertionConsumerServiceConverter.OPENID_PROTOCOL)) {
+            return CollectionSupport.singleton(new Namespace("urn:mace:shibboleth:metadata:oidc:1.0", "oidcmd"));
+        }
+        return null;
     }
     
     /**
@@ -332,9 +396,9 @@ public class MetadataGenCommandLineArguments extends AbstractIdPHomeAwareCommand
         super.printHelp(out);
         out.println(String.format("  %-20s %s", "--entityID, --client_id, --id", "The entityID (or client_id, etc.)"));
 
-        out.println(String.format("  %-20s %s", "--sp", "Output SP role."));
-        out.println(String.format("  %-20s %s", "--idp", "Output IdP role."));
-        out.println(String.format("  %-20s %s", "--aa", "Output Attribute Authority role."));
+        out.println(String.format("  %-20s %s", "--sp", "Include SP role."));
+        out.println(String.format("  %-20s %s", "--idp", "Include IdP role."));
+        out.println(String.format("  %-20s %s", "--aa", "Include Attribute Authority role."));
 
         out.println(String.format("  %-20s %s", "--sso", "Binding/Endpoint for SingleSignOnService"));
         out.println(String.format("  %-20s %s", "--logout, --slo", "Binding/Endpoint for SingleLogoutService"));
@@ -346,8 +410,14 @@ public class MetadataGenCommandLineArguments extends AbstractIdPHomeAwareCommand
         out.println(String.format("  %-20s %s", "--signing, -x", "Path to signing certificate."));
         out.println(String.format("  %-20s %s", "--encryption, -e", "Path to encryption certificate."));
         
+        out.println(String.format("  %-20s %s", "--want-assertions-signed, -w", "SP requires signed assertions?"));
+        out.println(String.format("  %-20s %s", "--nameid-format, -f", "SP NameID format(s)"));
+        
+        out.println(String.format("  %-20s %s", "--org-name, -o", "Organization name"));
+        out.println(String.format("  %-20s %s", "--org-url, -u", "Organization URL"));
+        
         out.println(String.format("  %-20s %s", "--omit-namespaces", "Omit namespaces on root element."));
-        out.println(String.format("  %-20s %s", "--output, -o", "Output file path."));
+        out.println(String.format("  %-20s %s", "--output, --out", "Output file path."));
         out.println();
     }
     
diff --git a/metadatagen-impl/src/test/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenTest.java b/metadatagen-impl/src/test/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenTest.java
index a623f2e..621fc72 100644
--- a/metadatagen-impl/src/test/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenTest.java
+++ b/metadatagen-impl/src/test/java/net/shibboleth/idp/plugin/metadatagen/impl/MetadataGenTest.java
@@ -19,6 +19,7 @@ package net.shibboleth.idp.plugin.metadatagen.impl;
 
 import static org.testng.Assert.assertEquals;
 
+import org.opensaml.saml.saml2.core.NameIDType;
 import org.testng.annotations.Test;
 
 import net.shibboleth.shared.cli.AbstractCommandLine;
@@ -31,13 +32,17 @@ public class MetadataGenTest {
     //   2) Edit the setting of the property 'idp.metadata.backchannel.cert' in
     //      src/test/resources/net/shibboleth/idp/plugin/metadatagen/impl/extra2
     private final static String IDP_HOME =  "/Users/scantor/Documents/shibboleth5/java-identity-provider/idp-conf-impl/src/main/resources/net/shibboleth/idp/module";
-    private final boolean enabled = false;
+    private final boolean enabled = true;
 
     @Test(enabled = enabled) public void testSimple() {
         assertEquals(MetadataGenCLI.runMain(
                 new String[] {
                         "--home", IDP_HOME,
-                        "--sp",
+                        "--lang", "US-en",
+                        "-o", "Example Org",
+                        "-u", "https://example.org",
+                        "--sp", "-w",
+                        "--nameid-format", NameIDType.EMAIL,
                         "--idp",
                         "--aa",
                         "--entityID", "https://sp.example.org",

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


More information about the commits mailing list