[java-opensaml] 01/01: OSJ-317 - Tighten Metadata schema to disallow empty elements.

Scott Cantor cantor.2 at osu.edu
Thu Jun 4 23:04:58 UTC 2020


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

scantor pushed a commit to branch dev/OSJ-317
in repository java-opensaml.

View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=5796c2cc9139bdd6d65db74d95a9a9511cdf5044

commit 5796c2cc9139bdd6d65db74d95a9a9511cdf5044
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Jun 4 19:04:40 2020 -0400

    OSJ-317 - Tighten Metadata schema to disallow empty elements.
    
    https://issues.shibboleth.net/jira/browse/OSJ-317
---
 .../opensaml/saml/common/xml/SAMLConstants.java    |  49 +++-
 .../saml/common/xml/SAMLSchemaBuilder.java         |  73 ++++-
 .../schema/strict/saml-metadata-rpi-v1.1.xsd       |  82 ++++++
 .../schema/strict/saml-schema-assertion-2.1.xsd    | 284 ++++++++++++++++++
 .../schema/strict/saml-schema-dce-2.1.xsd          |  27 ++
 .../schema/strict/saml-schema-ecp-2.1.xsd          |  80 +++++
 .../schema/strict/saml-schema-metadata-2.1.xsd     | 324 +++++++++++++++++++++
 .../schema/strict/saml-schema-protocol-2.1.xsd     | 290 ++++++++++++++++++
 .../schema/strict/saml-schema-x500-2.1.xsd         |  18 ++
 .../schema/strict/saml-schema-xacml-2.1.xsd        |  19 ++
 .../strict/sstc-saml-metadata-algsupport-v1.1.xsd  |  58 ++++
 .../schema/strict/sstc-saml-metadata-ext-query.xsd |  59 ++++
 .../schema/strict/sstc-saml-metadata-ui-v1.1.xsd   |  78 +++++
 .../filter/impl/SchemaValidationFilterTest.java    |  51 ++--
 .../saml/saml2/metadata/invalid-metadata.xml       | 133 +++++++++
 .../saml/saml2/metadata/valid-metadata.xml         | 133 +++++++++
 16 files changed, 1717 insertions(+), 41 deletions(-)

diff --git a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/xml/SAMLConstants.java b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/xml/SAMLConstants.java
index 53ea02e77..201cfce65 100644
--- a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/xml/SAMLConstants.java
+++ b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/xml/SAMLConstants.java
@@ -128,6 +128,9 @@ public final class SAMLConstants {
     /** SAML 2.0 Assertion schema Id. */
     public static final String SAML20_SCHEMA_LOCATION = SCHEMA_DIR + "saml-schema-assertion-2.0.xsd";
 
+    /** "Strict" SAML 2.0 Assertion schema Id. */
+    public static final String STRICT_SAML20_SCHEMA_LOCATION = SCHEMA_DIR + "strict/saml-schema-assertion-2.1.xsd";
+
     /** SAML 2.0 Assertion XML Namespace. */
     public static final String SAML20_NS = "urn:oasis:names:tc:SAML:2.0:assertion";
 
@@ -137,12 +140,24 @@ public final class SAMLConstants {
     /** SAML 2.0 Protocol schema Id. */
     public static final String SAML20P_SCHEMA_LOCATION = SCHEMA_DIR + "saml-schema-protocol-2.0.xsd";
 
+    /** "Strict" SAML 2.0 Protocol schema Id. */
+    public static final String STRICT_SAML20P_SCHEMA_LOCATION = SCHEMA_DIR + "strict/saml-schema-protocol-2.1.xsd";
+
     /** SAML 2.0 Protocol XML Namespace. */
     public static final String SAML20P_NS = "urn:oasis:names:tc:SAML:2.0:protocol";
 
     /** SAML 2.0 Protocol QName prefix. */
     public static final String SAML20P_PREFIX = "saml2p";
 
+    /** SAML 2.0 Metadata schema Id. */
+    public static final String SAML20MD_SCHEMA_LOCATION = SCHEMA_DIR + "saml-schema-metadata-2.0.xsd";
+
+    /** "Strict" SAML 2.0 Metadata schema Id. */
+    public static final String STRICT_SAML20MD_SCHEMA_LOCATION = SCHEMA_DIR + "strict/saml-schema-metadata-2.1.xsd";
+
+    /** SAML 2.0 Metadata XML Namespace. */
+    public static final String SAML20MD_NS = "urn:oasis:names:tc:SAML:2.0:metadata";
+    
     /** SAML 2.0 Protocol Third-party extension schema Id. */
     public static final String SAML20PTHRPTY_SCHEMA_LOCATION = SCHEMA_DIR + "sstc-saml-protocol-ext-thirdparty.xsd";
 
@@ -167,18 +182,16 @@ public final class SAMLConstants {
     /** SAML SAML V2.0 "Protocol Extension For Requesting Attributes Per Request" prefix. */
     public static final String SAML20PREQ_ATTRR_PREFIX = "req-attr";
 
-    /** SAML 2.0 Metadata schema Id. */
-    public static final String SAML20MD_SCHEMA_LOCATION = SCHEMA_DIR + "saml-schema-metadata-2.0.xsd";
-
-    /** SAML 2.0 Metadata XML Namespace. */
-    public static final String SAML20MD_NS = "urn:oasis:names:tc:SAML:2.0:metadata";
-
     /** SAML 2.0 Standalone Query Metadata extension XML namespace. */
     public static final String SAML20MDQUERY_NS = "urn:oasis:names:tc:SAML:metadata:ext:query";
 
     /** SAML 2.0 Standalone Query Metadata extension schema system Id. */
     public static final String SAML20MDQUERY_SCHEMA_LOCATION = SCHEMA_DIR + "sstc-saml-metadata-ext-query.xsd";
 
+    /** "Strict" SAML 2.0 Standalone Query Metadata extension schema system Id. */
+    public static final String STRICT_SAML20MDQUERY_SCHEMA_LOCATION =
+            SCHEMA_DIR + "strict/sstc-saml-metadata-ext-query.xsd";
+
     /** SAML 2.0 Standalone Query Metadata extension prefix. */
     public static final String SAML20MDQUERY_PREFIX = "query";
 
@@ -197,6 +210,9 @@ public final class SAMLConstants {
     /** SAML 2.0 Enhanced Client/Proxy SSO Profile schema Id. */
     public static final String SAML20ECP_SCHEMA_LOCATION = SCHEMA_DIR + "saml-schema-ecp-2.0.xsd";
 
+    /** "Strict" SAML 2.0 Enhanced Client/Proxy SSO Profile schema Id. */
+    public static final String STRICT_SAML20ECP_SCHEMA_LOCATION = SCHEMA_DIR + "strict/saml-schema-ecp-2.1.xsd";
+
     /** SAML 2.0 Enhanced Client/Proxy SSO Profile XML Namespace. */
     public static final String SAML20ECP_NS = "urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp";
 
@@ -224,6 +240,9 @@ public final class SAMLConstants {
     /** SAML 2.0 Metadata Extension for Discovery and Login UI schema Id. */
     public static final String SAML20MDUI_SCHEMA_LOCATION = SCHEMA_DIR + "sstc-saml-metadata-ui-v1.0.xsd";
 
+    /** "Strict" SAML 2.0 Metadata Extension for Discovery and Login UI schema Id. */
+    public static final String STRICT_SAML20MDUI_SCHEMA_LOCATION = SCHEMA_DIR + "strict/sstc-saml-metadata-ui-v1.1.xsd";
+
     /** SAML 2.0 Metadata Extension for Discovery and Login UI XML Namespace. */
     public static final String SAML20MDUI_NS = "urn:oasis:names:tc:SAML:metadata:ui";
 
@@ -239,6 +258,9 @@ public final class SAMLConstants {
     /** SAML 2.0 Metadata Extension for Registration and Publication Information schema Id. */
     public static final String SAML20MDRPI_SCHEMA_LOCATION = SCHEMA_DIR + "saml-metadata-rpi-v1.0.xsd";
 
+    /** "Strict" SAML 2.0 Metadata Extension for Registration and Publication Information schema Id. */
+    public static final String STRICT_SAML20MDRPI_SCHEMA_LOCATION = SCHEMA_DIR + "strict/saml-metadata-rpi-v1.1.xsd";
+
     /** SAML 2.0 Metadata Extension for Registration and Publication Information XML Namespace. */
     public static final String SAML20MDRPI_NS = "urn:oasis:names:tc:SAML:metadata:rpi";
 
@@ -257,6 +279,9 @@ public final class SAMLConstants {
     /** SAML 2.0 DCE PAC Attribute Profile schema Id. */
     public static final String SAML20DCE_SCHEMA_LOCATION = SCHEMA_DIR + "saml-schema-dce-2.0.xsd";
 
+    /** "Strict" SAML 2.0 DCE PAC Attribute Profile schema Id. */
+    public static final String STRICT_SAML20DCE_SCHEMA_LOCATION = SCHEMA_DIR + "strict/saml-schema-dce-2.1.xsd";
+
     /** SAML 2.0 DCE PAC Attribute Profile XML Namespace. */
     public static final String SAML20DCE_NS = "urn:oasis:names:tc:SAML:2.0:profiles:attribute:DCE";
 
@@ -266,6 +291,9 @@ public final class SAMLConstants {
     /** SAML 2.0 X.500 Attribute Profile schema Id. */
     public static final String SAML20X500_SCHEMA_LOCATION = SCHEMA_DIR + "saml-schema-x500-2.0.xsd";
 
+    /** "Strict" SAML 2.0 X.500 Attribute Profile schema Id. */
+    public static final String STRICT_SAML20X500_SCHEMA_LOCATION = SCHEMA_DIR + "strict/saml-schema-x500-2.1.xsd";
+
     /** SAML 2.0 X.500 Attribute Profile XML Namespace. */
     public static final String SAML20X500_NS = "urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500";
 
@@ -275,6 +303,9 @@ public final class SAMLConstants {
     /** SAML 2.0 XACML Attribute Profile schema Id. */
     public static final String SAML20XACML_SCHEMA_LOCATION = SCHEMA_DIR + "saml-schema-xacml-2.0.xsd";
 
+    /** "Strict" SAML 2.0 XACML Attribute Profile schema Id. */
+    public static final String STRICT_SAML20XACML_SCHEMA_LOCATION = SCHEMA_DIR + "strict/saml-schema-xacml-2.1.xsd";
+
     /** SAML 2.0 XACML Attribute Profile XML Namespace. */
     public static final String SAML20XACML_NS = "urn:oasis:names:tc:SAML:2.0:profiles:attribute:XACML";
 
@@ -320,7 +351,11 @@ public final class SAMLConstants {
     
     /** SAML 2.0 Metadata Profile for Algorithm Support schema Id. */
     public static final String SAML20ALG_SCHEMA_LOCATION = SCHEMA_DIR + "sstc-saml-metadata-algsupport-v1.0.xsd";
-    
+
+    /** "Strict" SAML 2.0 Metadata Profile for Algorithm Support schema Id. */
+    public static final String STRICT_SAML20ALG_SCHEMA_LOCATION =
+            SCHEMA_DIR + "strict/sstc-saml-metadata-algsupport-v1.1.xsd";
+
     /** SAML 2.0 Metadata Profile for Algorithm Support Namespace. */
     public static final String SAML20ALG_NS = "urn:oasis:names:tc:SAML:metadata:algsupport";
     
diff --git a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/xml/SAMLSchemaBuilder.java b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/xml/SAMLSchemaBuilder.java
index bcee3bd5b..532f1135e 100644
--- a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/xml/SAMLSchemaBuilder.java
+++ b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/xml/SAMLSchemaBuilder.java
@@ -77,11 +77,8 @@ public class SAMLSchemaBuilder {
         SAMLConstants.SAML11P_SCHEMA_LOCATION,
         };
 
-    /** Classpath relative location of SAML 2_0 schemas. */
-    @Nonnull @NonnullElements @NotEmpty private static String[] saml20Schemas = {
-        SAMLConstants.SAML20_SCHEMA_LOCATION,
-        SAMLConstants.SAML20P_SCHEMA_LOCATION,
-        SAMLConstants.SAML20MD_SCHEMA_LOCATION,
+    /** Classpath relative location of the invariant SAML 2.0 schemas. */
+    @Nonnull @NonnullElements @NotEmpty private static String[] saml20CommonSchemas = {
         SAMLConstants.SAML20AC_SCHEMA_LOCATION,
         "/schema/saml-schema-authn-context-auth-telephony-2.0.xsd",
         "/schema/saml-schema-authn-context-ip-2.0.xsd",
@@ -107,23 +104,47 @@ public class SAMLSchemaBuilder {
         "/schema/saml-schema-authn-context-timesync-2.0.xsd",
         "/schema/saml-schema-authn-context-x509-2.0.xsd",
         "/schema/saml-schema-authn-context-xmldsig-2.0.xsd",
+        };
+
+    /** Classpath relative location of SAML 2_0 schemas. */
+    @Nonnull @NonnullElements @NotEmpty private static String[] saml20Schemas = {
+        SAMLConstants.SAML20_SCHEMA_LOCATION,
+        SAMLConstants.SAML20P_SCHEMA_LOCATION,
+        SAMLConstants.SAML20MD_SCHEMA_LOCATION,
         SAMLConstants.SAML20DCE_SCHEMA_LOCATION,
         SAMLConstants.SAML20ECP_SCHEMA_LOCATION,
         SAMLConstants.SAML20X500_SCHEMA_LOCATION,
         SAMLConstants.SAML20XACML_SCHEMA_LOCATION,
+        // Start of extensions
+        SAMLConstants.SAML20MDQUERY_SCHEMA_LOCATION,
+        SAMLConstants.SAML20MDUI_SCHEMA_LOCATION,
+        SAMLConstants.SAML20MDRPI_SCHEMA_LOCATION,
+        SAMLConstants.SAML20ALG_SCHEMA_LOCATION,
         };
 
+    /** Classpath relative location of SAML 2_0 schemas with strict string/anyURI types. */
+    @Nonnull @NonnullElements @NotEmpty private static String[] saml20StrictSchemas = {
+        SAMLConstants.STRICT_SAML20_SCHEMA_LOCATION,
+        SAMLConstants.STRICT_SAML20P_SCHEMA_LOCATION,
+        SAMLConstants.STRICT_SAML20MD_SCHEMA_LOCATION,
+        SAMLConstants.STRICT_SAML20DCE_SCHEMA_LOCATION,
+        SAMLConstants.STRICT_SAML20ECP_SCHEMA_LOCATION,
+        SAMLConstants.STRICT_SAML20X500_SCHEMA_LOCATION,
+        SAMLConstants.STRICT_SAML20XACML_SCHEMA_LOCATION,
+        // Start of extensions
+        SAMLConstants.STRICT_SAML20MDQUERY_SCHEMA_LOCATION,
+        SAMLConstants.STRICT_SAML20MDUI_SCHEMA_LOCATION,
+        SAMLConstants.STRICT_SAML20MDRPI_SCHEMA_LOCATION,
+        SAMLConstants.STRICT_SAML20ALG_SCHEMA_LOCATION,
+        };
+    
     /** Classpath relative location of SAML extension schemas. */
     @Nonnull @NonnullElements @NotEmpty private static String[] baseExtSchemas = {
         SAMLConstants.SAML1MD_SCHEMA_LOCATION,
         SAMLConstants.SAML_IDP_DISCO_SCHEMA_LOCATION,
         SAMLConstants.SAML20PTHRPTY_SCHEMA_LOCATION,
-        SAMLConstants.SAML20MDQUERY_SCHEMA_LOCATION,
         SAMLConstants.SAML20DEL_SCHEMA_LOCATION,
-        SAMLConstants.SAML20MDUI_SCHEMA_LOCATION,
         SAMLConstants.SAML20MDATTR_SCHEMA_LOCATION,
-        SAMLConstants.SAML20MDRPI_SCHEMA_LOCATION,
-        SAMLConstants.SAML20ALG_SCHEMA_LOCATION,
         SAMLConstants.SAML20CB_SCHEMA_LOCATION,
         SAMLConstants.SAML20PASLO_SCHEMA_LOCATION,
         SAMLConstants.SAMLEC_GSS_SCHEMA_LOCATION,
@@ -131,7 +152,7 @@ public class SAMLSchemaBuilder {
     
       
     /** Logger. */
-    private Logger log = LoggerFactory.getLogger(SAMLSchemaBuilder.class);
+    @Nonnull private Logger log = LoggerFactory.getLogger(SAMLSchemaBuilder.class);
     
     /** Flag indicating whether the failure to resolve a schema resource should be considered fatal. */
     private boolean unresolvedSchemaFatal;
@@ -141,7 +162,10 @@ public class SAMLSchemaBuilder {
 
     /** Reference to SAML 1.x schemas to apply. */
     @Nonnull @NonnullElements @NotEmpty private String[] saml1xSchemas;
-    
+
+    /** Reference to SAML 2.0 schemas to apply. */
+    @Nonnull @NonnullElements @NotEmpty private String[] saml2Schemas;
+
     /** The builder to use. */
     @Nonnull private SchemaBuilder schemaBuilder;
     
@@ -164,14 +188,33 @@ public class SAMLSchemaBuilder {
      * @param ver   the SAML 1.x version to use
      */
     public SAMLSchemaBuilder(@Nonnull @ParameterName(name="ver") final SAML1Version ver) {
+        this(ver, false);
+    }
+
+    /**
+     * Constructor.
+     * 
+     * <p>A default {@link SchemaBuilder} is constructed, and injected with a
+     * {@link ClasspathResolver} for resolving supplementary schemas.
+     * 
+     * @param ver   the SAML 1.x version to use
+     * @param strict whether to apply modified schemas with strict string and anyURI type definitions
+     */
+    public SAMLSchemaBuilder(@Nonnull @ParameterName(name="ver") final SAML1Version ver,
+            @ParameterName(name="strict") final boolean strict) {
         unresolvedSchemaFatal = true;
         if (ver == SAML1Version.SAML_11) {
             saml1xSchemas = saml11Schemas;
         } else {
             saml1xSchemas = saml10Schemas;
         }
+        if (strict) {
+            saml2Schemas = saml20StrictSchemas;
+        } else {
+            saml2Schemas = saml20Schemas;
+        }
     }
-    
+
     /**
      * Set the flag indicating whether the failure to resolve a schema resource should be considered fatal.
      * 
@@ -234,10 +277,14 @@ public class SAMLSchemaBuilder {
             addSchemaToBuilder(source);
         }
 
-        for (final String source : saml20Schemas) {
+        for (final String source : saml2Schemas) {
             addSchemaToBuilder(source);
         }
 
+        for (final String source : saml20CommonSchemas) {
+            addSchemaToBuilder(source);
+        }
+        
         for (final String source : baseExtSchemas) {
             addSchemaToBuilder(source);
         }
diff --git a/opensaml-saml-api/src/main/resources/schema/strict/saml-metadata-rpi-v1.1.xsd b/opensaml-saml-api/src/main/resources/schema/strict/saml-metadata-rpi-v1.1.xsd
new file mode 100644
index 000000000..cd6fcec11
--- /dev/null
+++ b/opensaml-saml-api/src/main/resources/schema/strict/saml-metadata-rpi-v1.1.xsd
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  SAML V2.0 Metadata Extensions for Registration and Publication Information Version 1.0
+  Committee Specification 01
+  03 April 2012
+  Copyright (c) OASIS Open 2012.  All rights reserved.
+  Source: http://docs.oasis-open.org/security/saml/Post2.0/saml-metadata-rpi/v1.0/cs01/xsd/
+-->
+
+<schema targetNamespace="urn:oasis:names:tc:SAML:metadata:rpi"
+    xmlns="http://www.w3.org/2001/XMLSchema"
+    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+    xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+    xmlns:mdrpi="urn:oasis:names:tc:SAML:metadata:rpi"
+    elementFormDefault="unqualified" 
+    attributeFormDefault="unqualified" 
+    blockDefault="substitution" 
+    version="1.1"> 
+
+    <annotation>
+        <documentation>
+            Document title: SAML V2.0 Metadata Extensions for Registration and Publication Information Version 1.0
+            Document identifier: sstc-saml-metadata-rpi-v1.1.xsd
+            Revision history:
+              21 March 2011
+                Correct minOccurs on elements that were meant to be optional              
+              17 December 2010
+                Change of document title and namespace
+              24 November 2010
+                Initial Submission
+              June 2020
+                Private Shibboleth version to tighten string and anyURI minLength
+        </documentation>
+    </annotation>
+    
+    <import namespace="urn:oasis:names:tc:SAML:2.0:assertion" schemaLocation="saml-schema-assertion-2.1.xsd"/>
+    <import namespace="urn:oasis:names:tc:SAML:2.0:metadata" schemaLocation="saml-schema-metadata-2.1.xsd"/>
+    <import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+    
+    <element name="RegistrationInfo" type="mdrpi:RegistrationInfoType" />
+    <complexType name="RegistrationInfoType">
+        <sequence>
+            <element ref="mdrpi:RegistrationPolicy" minOccurs="0" maxOccurs="unbounded" />
+            <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+        </sequence>
+        <attribute name="registrationAuthority" type="saml:string" use="required"/>
+        <attribute name="registrationInstant" type="dateTime" />
+        <anyAttribute namespace="##other" processContents="lax" />
+    </complexType>
+    
+    <element name="RegistrationPolicy" type="md:localizedURIType" />
+    
+    <element name="PublicationInfo" type="mdrpi:PublicationInfoType" />
+    <complexType name="PublicationInfoType">
+        <sequence>
+            <element ref="mdrpi:UsagePolicy" minOccurs="0" maxOccurs="unbounded"/>
+            <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+        </sequence>
+        <attribute name="publisher" type="saml:string" use="required" />
+        <attribute name="creationInstant" type="dateTime" />
+        <attribute name="publicationId" type="saml:string" />
+        <anyAttribute namespace="##other" processContents="lax" />
+    </complexType>
+    
+    <element name="UsagePolicy" type="md:localizedURIType" />
+    
+    <element name="PublicationPath" type="mdrpi:PublicationPathType" />
+    <complexType name="PublicationPathType">
+        <sequence>
+            <element ref="mdrpi:Publication" minOccurs="0" maxOccurs="unbounded" />
+        </sequence>
+    </complexType>
+    
+    <element name="Publication" type="mdrpi:PublicationType" />
+    <complexType name="PublicationType">
+        <attribute name="publisher" type="saml:string" use="required" />
+        <attribute name="creationInstant" type="dateTime" />
+        <attribute name="publicationId" type="saml:string" />
+    </complexType>
+    
+</schema>
\ No newline at end of file
diff --git a/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-assertion-2.1.xsd b/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-assertion-2.1.xsd
new file mode 100644
index 000000000..681faa328
--- /dev/null
+++ b/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-assertion-2.1.xsd
@@ -0,0 +1,284 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" targetNamespace="urn:oasis:names:tc:SAML:2.0:assertion" elementFormDefault="unqualified" attributeFormDefault="unqualified" blockDefault="substitution" version="2.1">
+        
+    <import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd"/>
+    <import namespace="http://www.w3.org/2001/04/xmlenc#" schemaLocation="http://www.w3.org/TR/xmlenc-core/xenc-schema.xsd"/>
+    
+    <annotation>
+        <documentation>
+            Document identifier: saml-schema-assertion-2.1
+            Revision history:
+            V1.0 (November, 2002): Initial Standard Schema.
+            V1.1 (September, 2003): Updates within the same V1.0 namespace.
+            V2.0 (March, 2005): New assertion schema for SAML V2.0 namespace.
+            V2.1 (June 2020): Private Shibboleth version to tighten string and anyURI minLength.
+        </documentation>
+    </annotation>
+    
+  <simpleType name="string">
+    <restriction base="string">
+      <minLength value="1"/>
+    </restriction>
+  </simpleType>
+
+  <simpleType name="anyURI">
+    <restriction base="anyURI">
+      <minLength value="1"/>
+    </restriction>
+  </simpleType>
+    
+    <attributeGroup name="IDNameQualifiers">
+        <attribute name="NameQualifier" type="saml:string" use="optional"/>
+        <attribute name="SPNameQualifier" type="saml:string" use="optional"/>
+    </attributeGroup>
+    <element name="BaseID" type="saml:BaseIDAbstractType"/>
+    <complexType name="BaseIDAbstractType" abstract="true">
+        <attributeGroup ref="saml:IDNameQualifiers"/>
+    </complexType>
+    <element name="NameID" type="saml:NameIDType"/>
+    <complexType name="NameIDType">
+        <simpleContent>
+            <extension base="string">
+                <attributeGroup ref="saml:IDNameQualifiers"/>
+                <attribute name="Format" type="saml:anyURI" use="optional"/>
+                <attribute name="SPProvidedID" type="saml:string" use="optional"/>
+            </extension>
+        </simpleContent>
+    </complexType>
+    <complexType name="EncryptedElementType">
+        <sequence>
+            <element ref="xenc:EncryptedData"/>
+            <element ref="xenc:EncryptedKey" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+    </complexType>
+    <element name="EncryptedID" type="saml:EncryptedElementType"/>
+    <element name="Issuer" type="saml:NameIDType"/>
+    <element name="AssertionIDRef" type="NCName"/>
+    <element name="AssertionURIRef" type="saml:anyURI"/>
+    <element name="Assertion" type="saml:AssertionType"/>
+    <complexType name="AssertionType">
+        <sequence>
+            <element ref="saml:Issuer"/>
+            <element ref="ds:Signature" minOccurs="0"/>
+            <element ref="saml:Subject" minOccurs="0"/>
+            <element ref="saml:Conditions" minOccurs="0"/>
+            <element ref="saml:Advice" minOccurs="0"/>
+            <choice minOccurs="0" maxOccurs="unbounded">
+                <element ref="saml:Statement"/>
+                <element ref="saml:AuthnStatement"/>
+                <element ref="saml:AuthzDecisionStatement"/>
+                <element ref="saml:AttributeStatement"/>
+            </choice>
+        </sequence>
+        <attribute name="Version" type="saml:string" use="required"/>
+        <attribute name="ID" type="ID" use="required"/>
+        <attribute name="IssueInstant" type="dateTime" use="required"/>
+    </complexType>
+    <element name="Subject" type="saml:SubjectType"/>
+    <complexType name="SubjectType">
+        <choice>
+            <sequence>
+                <choice>
+                    <element ref="saml:BaseID"/>
+                    <element ref="saml:NameID"/>
+                    <element ref="saml:EncryptedID"/>
+                </choice>
+                <element ref="saml:SubjectConfirmation" minOccurs="0" maxOccurs="unbounded"/>
+            </sequence>
+            <element ref="saml:SubjectConfirmation" maxOccurs="unbounded"/>
+        </choice>
+    </complexType>
+    <element name="SubjectConfirmation" type="saml:SubjectConfirmationType"/>
+    <complexType name="SubjectConfirmationType">
+        <sequence>
+            <choice minOccurs="0">
+                <element ref="saml:BaseID"/>
+                <element ref="saml:NameID"/>
+                <element ref="saml:EncryptedID"/>
+            </choice>
+            <element ref="saml:SubjectConfirmationData" minOccurs="0"/>
+        </sequence>
+        <attribute name="Method" type="saml:anyURI" use="required"/>
+    </complexType>
+    <element name="SubjectConfirmationData" type="saml:SubjectConfirmationDataType"/>
+    <complexType name="SubjectConfirmationDataType" mixed="true">
+        <complexContent>
+            <restriction base="anyType">
+                <sequence>
+                    <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+                <attribute name="NotBefore" type="dateTime" use="optional"/>
+                <attribute name="NotOnOrAfter" type="dateTime" use="optional"/>
+                <attribute name="Recipient" type="saml:anyURI" use="optional"/>
+                <attribute name="InResponseTo" type="NCName" use="optional"/>
+                <attribute name="Address" type="saml:string" use="optional"/>
+                <anyAttribute namespace="##other" processContents="lax"/>
+            </restriction>
+        </complexContent>
+    </complexType>
+    <complexType name="KeyInfoConfirmationDataType" mixed="false">
+        <complexContent>
+            <restriction base="saml:SubjectConfirmationDataType">
+                <sequence>
+                    <element ref="ds:KeyInfo" maxOccurs="unbounded"/>
+                </sequence>
+            </restriction>
+        </complexContent>
+    </complexType>
+    <element name="Conditions" type="saml:ConditionsType"/>
+    <complexType name="ConditionsType">
+        <choice minOccurs="0" maxOccurs="unbounded">
+            <element ref="saml:Condition"/>
+            <element ref="saml:AudienceRestriction"/>
+            <element ref="saml:OneTimeUse"/>
+            <element ref="saml:ProxyRestriction"/>
+        </choice>
+        <attribute name="NotBefore" type="dateTime" use="optional"/>
+        <attribute name="NotOnOrAfter" type="dateTime" use="optional"/>
+    </complexType>
+    <element name="Condition" type="saml:ConditionAbstractType"/>
+    <complexType name="ConditionAbstractType" abstract="true"/>
+    <element name="AudienceRestriction" type="saml:AudienceRestrictionType"/>
+    <complexType name="AudienceRestrictionType">
+        <complexContent>
+            <extension base="saml:ConditionAbstractType">
+                <sequence>
+                    <element ref="saml:Audience" maxOccurs="unbounded"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="Audience" type="saml:anyURI"/>
+    <element name="OneTimeUse" type="saml:OneTimeUseType"/>
+    <complexType name="OneTimeUseType">
+        <complexContent>
+            <extension base="saml:ConditionAbstractType"/>
+        </complexContent>
+    </complexType>
+    <element name="ProxyRestriction" type="saml:ProxyRestrictionType"/>
+    <complexType name="ProxyRestrictionType">
+        <complexContent>
+            <extension base="saml:ConditionAbstractType">
+                <sequence>
+                    <element ref="saml:Audience" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+                <attribute name="Count" type="nonNegativeInteger" use="optional"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="Advice" type="saml:AdviceType"/>
+    <complexType name="AdviceType">
+        <choice minOccurs="0" maxOccurs="unbounded">
+            <element ref="saml:AssertionIDRef"/>
+            <element ref="saml:AssertionURIRef"/>
+            <element ref="saml:Assertion"/>
+            <element ref="saml:EncryptedAssertion"/>
+            <any namespace="##other" processContents="lax"/>
+        </choice>
+    </complexType>
+    <element name="EncryptedAssertion" type="saml:EncryptedElementType"/>
+    <element name="Statement" type="saml:StatementAbstractType"/>
+    <complexType name="StatementAbstractType" abstract="true"/>
+    <element name="AuthnStatement" type="saml:AuthnStatementType"/>
+    <complexType name="AuthnStatementType">
+        <complexContent>
+            <extension base="saml:StatementAbstractType">
+                <sequence>
+                    <element ref="saml:SubjectLocality" minOccurs="0"/>
+                    <element ref="saml:AuthnContext"/>
+                </sequence>
+                <attribute name="AuthnInstant" type="dateTime" use="required"/>
+                <attribute name="SessionIndex" type="saml:string" use="optional"/>
+                <attribute name="SessionNotOnOrAfter" type="dateTime" use="optional"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="SubjectLocality" type="saml:SubjectLocalityType"/>
+    <complexType name="SubjectLocalityType">
+        <attribute name="Address" type="saml:string" use="optional"/>
+        <attribute name="DNSName" type="saml:string" use="optional"/>
+    </complexType>
+    <element name="AuthnContext" type="saml:AuthnContextType"/>
+    <complexType name="AuthnContextType">
+        <sequence>
+            <choice>
+                <sequence>
+                    <element ref="saml:AuthnContextClassRef"/>
+                    <choice minOccurs="0">
+                        <element ref="saml:AuthnContextDecl"/>
+                        <element ref="saml:AuthnContextDeclRef"/>
+                    </choice>
+                </sequence>
+                <choice>
+                    <element ref="saml:AuthnContextDecl"/>
+                    <element ref="saml:AuthnContextDeclRef"/>
+                </choice>
+            </choice>
+            <element ref="saml:AuthenticatingAuthority" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+    </complexType>
+    <element name="AuthnContextClassRef" type="saml:anyURI"/>
+    <element name="AuthnContextDeclRef" type="saml:anyURI"/>
+    <element name="AuthnContextDecl" type="anyType"/>
+    <element name="AuthenticatingAuthority" type="saml:anyURI"/>
+    <element name="AuthzDecisionStatement" type="saml:AuthzDecisionStatementType"/>
+    <complexType name="AuthzDecisionStatementType">
+        <complexContent>
+            <extension base="saml:StatementAbstractType">
+                <sequence>
+                    <element ref="saml:Action" maxOccurs="unbounded"/>
+                    <element ref="saml:Evidence" minOccurs="0"/>
+                </sequence>
+                <attribute name="Resource" type="saml:anyURI" use="required"/>
+                <attribute name="Decision" type="saml:DecisionType" use="required"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <simpleType name="DecisionType">
+        <restriction base="string">
+            <enumeration value="Permit"/>
+            <enumeration value="Deny"/>
+            <enumeration value="Indeterminate"/>
+        </restriction>
+    </simpleType>
+    <element name="Action" type="saml:ActionType"/>
+    <complexType name="ActionType">
+        <simpleContent>
+            <extension base="string">
+                <attribute name="Namespace" type="saml:anyURI" use="required"/>
+            </extension>
+        </simpleContent>
+    </complexType>
+    <element name="Evidence" type="saml:EvidenceType"/>
+    <complexType name="EvidenceType">
+        <choice maxOccurs="unbounded">
+            <element ref="saml:AssertionIDRef"/>
+            <element ref="saml:AssertionURIRef"/>
+            <element ref="saml:Assertion"/>
+            <element ref="saml:EncryptedAssertion"/>
+        </choice>
+    </complexType>
+    <element name="AttributeStatement" type="saml:AttributeStatementType"/>
+    <complexType name="AttributeStatementType">
+        <complexContent>
+            <extension base="saml:StatementAbstractType">
+                <choice maxOccurs="unbounded">
+                    <element ref="saml:Attribute"/>
+                    <element ref="saml:EncryptedAttribute"/>
+                </choice>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="Attribute" type="saml:AttributeType"/>
+    <complexType name="AttributeType">
+        <sequence>
+            <element ref="saml:AttributeValue" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+        <attribute name="Name" type="saml:string" use="required"/>
+        <attribute name="NameFormat" type="saml:anyURI" use="optional"/>
+        <attribute name="FriendlyName" type="saml:string" use="optional"/>
+        <anyAttribute namespace="##other" processContents="lax"/>
+    </complexType>
+    <element name="AttributeValue" type="anyType" nillable="true"/>
+    <element name="EncryptedAttribute" type="saml:EncryptedElementType"/>
+</schema>
diff --git a/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-dce-2.1.xsd b/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-dce-2.1.xsd
new file mode 100644
index 000000000..d17844677
--- /dev/null
+++ b/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-dce-2.1.xsd
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns:dce="urn:oasis:names:tc:SAML:2.0:profiles:attribute:DCE" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" targetNamespace="urn:oasis:names:tc:SAML:2.0:profiles:attribute:DCE" elementFormDefault="unqualified" attributeFormDefault="unqualified" blockDefault="substitution" version="2.0">
+    
+    <annotation>
+        <documentation>
+            Document identifier: saml-schema-dce-2.1
+            Revision history:
+            V2.0 (March, 2005):
+                Custom schema for DCE attribute profile, first published in SAML 2.0.
+            V2.1 (June 2020):
+                Private Shibboleth version to tighten string and anyURI minLength.
+        </documentation>
+    </annotation>
+    
+    <import namespace="urn:oasis:names:tc:SAML:2.0:assertion" schemaLocation="saml-schema-assertion-2.1.xsd"/>
+    
+    <complexType name="DCEValueType">
+        <simpleContent>
+            <extension base="saml:anyURI">
+                <attribute ref="dce:Realm" use="optional"/>
+                <attribute ref="dce:FriendlyName" use="optional"/>
+            </extension>
+        </simpleContent>
+    </complexType>
+    <attribute name="Realm" type="saml:anyURI"/>
+    <attribute name="FriendlyName" type="saml:string"/>
+</schema>
diff --git a/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-ecp-2.1.xsd b/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-ecp-2.1.xsd
new file mode 100644
index 000000000..21ee4ca59
--- /dev/null
+++ b/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-ecp-2.1.xsd
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema
+    targetNamespace="urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp"
+    xmlns="http://www.w3.org/2001/XMLSchema"
+    xmlns:ecp="urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp"
+    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
+    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+    xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
+    elementFormDefault="unqualified"
+    attributeFormDefault="unqualified"
+    blockDefault="substitution"
+    version="2.0-v2.1">
+
+    <import namespace="urn:oasis:names:tc:SAML:2.0:protocol"
+        schemaLocation="saml-schema-protocol-2.1.xsd"/>
+    <import namespace="urn:oasis:names:tc:SAML:2.0:assertion"
+        schemaLocation="saml-schema-assertion-2.1.xsd"/>
+    <import namespace="http://schemas.xmlsoap.org/soap/envelope/"/>
+
+    <annotation>
+        <documentation>
+            Document identifier: saml-schema-ecp-2.0
+            Location: http://docs.oasis-open.org/security/saml/v2.0/
+            Revision history:
+              V2.0 (March, 2005):
+                Custom schema for ECP profile, first published in SAML 2.0.
+              V2.0-v2.0 (February 2013):
+                Updated version, published with Version 2.0 of ECP profile.
+              V2.0-2.1 (June 2020):
+                Private Shibboleth version to tighten string and anyURI minLength.
+        </documentation>
+    </annotation>
+
+    <element name="Request" type="ecp:RequestType"/>
+    <complexType name="RequestType">
+        <sequence>
+            <element ref="saml:Issuer"/>
+            <element ref="samlp:IDPList" minOccurs="0"/>
+        </sequence>
+        <attribute ref="S:mustUnderstand" use="required"/>
+        <attribute ref="S:actor" use="required"/>
+        <attribute name="ProviderName" type="saml:string" use="optional"/>
+        <attribute name="IsPassive" type="boolean" use="optional"/>
+    </complexType>
+    
+    <element name="Response" type="ecp:ResponseType"/>
+    <complexType name="ResponseType">
+        <attribute ref="S:mustUnderstand" use="required"/>
+        <attribute ref="S:actor" use="required"/>
+        <attribute name="AssertionConsumerServiceURL" type="saml:anyURI" use="required"/>
+    </complexType>
+    
+    <element name="RelayState" type="ecp:RelayStateType"/>
+    <complexType name="RelayStateType">
+        <simpleContent>
+            <extension base="string">
+                <attribute ref="S:mustUnderstand" use="required"/>
+                <attribute ref="S:actor" use="required"/>
+            </extension>
+        </simpleContent>
+    </complexType>
+    
+    <element name="SubjectConfirmation" type="ecp:SubjectConfirmationType"/>
+    <complexType name="SubjectConfirmationType">
+        <sequence>
+            <element ref="saml:SubjectConfirmationData" minOccurs="0"/>
+        </sequence>
+        <attribute ref="S:mustUnderstand" use="required"/>
+        <attribute ref="S:actor" use="required"/>
+        <attribute name="Method" type="saml:anyURI" use="required"/>
+    </complexType>
+
+    <element name="RequestAuthenticated" type="ecp:RequestAuthenticatedType"/>
+    <complexType name="RequestAuthenticatedType">
+        <sequence/>
+        <attribute ref="S:mustUnderstand"/>
+        <attribute ref="S:actor" use="required"/>
+    </complexType>
+
+</schema>
diff --git a/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-metadata-2.1.xsd b/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-metadata-2.1.xsd
new file mode 100644
index 000000000..7c5ee8ada
--- /dev/null
+++ b/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-metadata-2.1.xsd
@@ -0,0 +1,324 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:oasis:names:tc:SAML:2.0:metadata" elementFormDefault="unqualified" attributeFormDefault="unqualified" blockDefault="substitution" version="2.1">
+    <import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd"/>
+    <import namespace="http://www.w3.org/2001/04/xmlenc#" schemaLocation="http://www.w3.org/TR/xmlenc-core/xenc-schema.xsd"/>
+    <import namespace="urn:oasis:names:tc:SAML:2.0:assertion" schemaLocation="saml-schema-assertion-2.1.xsd"/>
+    <import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+    <annotation>
+        <documentation>
+            Document identifier: saml-schema-metadata-2.0
+            Revision history:
+              V2.0 (March, 2005):
+                Schema for SAML metadata, first published in SAML 2.0.
+              V2.1 (June 2020):
+                Private Shibboleth version to tighten string and anyURI minLength.
+        </documentation>
+    </annotation>
+
+    <simpleType name="entityIDType">
+        <restriction base="saml:anyURI">
+            <maxLength value="1024"/>
+        </restriction>
+    </simpleType>
+    <complexType name="localizedNameType">
+        <simpleContent>
+            <extension base="saml:string">
+                <attribute ref="xml:lang" use="required"/>
+            </extension>
+        </simpleContent>
+    </complexType>
+    <complexType name="localizedURIType">
+        <simpleContent>
+            <extension base="saml:anyURI">
+                <attribute ref="xml:lang" use="required"/>
+            </extension>
+        </simpleContent>
+    </complexType>
+    
+    <element name="Extensions" type="md:ExtensionsType"/>
+    <complexType final="#all" name="ExtensionsType">
+        <sequence>
+            <any namespace="##other" processContents="lax" maxOccurs="unbounded"/>
+        </sequence>
+    </complexType>
+    
+    <complexType name="EndpointType">
+        <sequence>
+            <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+        <attribute name="Binding" type="saml:anyURI" use="required"/>
+        <attribute name="Location" type="saml:anyURI" use="required"/>
+        <attribute name="ResponseLocation" type="saml:anyURI" use="optional"/>
+        <anyAttribute namespace="##other" processContents="lax"/>
+    </complexType>
+    
+    <complexType name="IndexedEndpointType">
+        <complexContent>
+            <extension base="md:EndpointType">
+                <attribute name="index" type="unsignedShort" use="required"/>
+                <attribute name="isDefault" type="boolean" use="optional"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    
+    <element name="EntitiesDescriptor" type="md:EntitiesDescriptorType"/>
+    <complexType name="EntitiesDescriptorType">
+        <sequence>
+            <element ref="ds:Signature" minOccurs="0"/>
+            <element ref="md:Extensions" minOccurs="0"/>
+            <choice minOccurs="1" maxOccurs="unbounded">
+                <element ref="md:EntityDescriptor"/>
+                <element ref="md:EntitiesDescriptor"/>
+            </choice>
+        </sequence>
+        <attribute name="validUntil" type="dateTime" use="optional"/>
+        <attribute name="cacheDuration" type="duration" use="optional"/>
+        <attribute name="ID" type="ID" use="optional"/>
+        <attribute name="Name" type="saml:string" use="optional"/>
+    </complexType>
+
+    <element name="EntityDescriptor" type="md:EntityDescriptorType"/>
+    <complexType name="EntityDescriptorType">
+        <sequence>
+            <element ref="ds:Signature" minOccurs="0"/>
+            <element ref="md:Extensions" minOccurs="0"/>
+            <choice>
+                <choice maxOccurs="unbounded">
+                    <element ref="md:RoleDescriptor"/>
+                    <element ref="md:IDPSSODescriptor"/>
+                    <element ref="md:SPSSODescriptor"/>
+                    <element ref="md:AuthnAuthorityDescriptor"/>
+                    <element ref="md:AttributeAuthorityDescriptor"/>
+                    <element ref="md:PDPDescriptor"/>
+                </choice>
+                <element ref="md:AffiliationDescriptor"/>
+            </choice>
+            <element ref="md:Organization" minOccurs="0"/>
+            <element ref="md:ContactPerson" minOccurs="0" maxOccurs="unbounded"/>
+            <element ref="md:AdditionalMetadataLocation" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+        <attribute name="entityID" type="md:entityIDType" use="required"/>
+        <attribute name="validUntil" type="dateTime" use="optional"/>
+        <attribute name="cacheDuration" type="duration" use="optional"/>
+        <attribute name="ID" type="ID" use="optional"/>
+        <anyAttribute namespace="##other" processContents="lax"/>
+    </complexType>
+    
+    <element name="Organization" type="md:OrganizationType"/>
+    <complexType name="OrganizationType">
+        <sequence>
+            <element ref="md:Extensions" minOccurs="0"/>
+            <element ref="md:OrganizationName" maxOccurs="unbounded"/>
+            <element ref="md:OrganizationDisplayName" maxOccurs="unbounded"/>
+            <element ref="md:OrganizationURL" maxOccurs="unbounded"/>
+        </sequence>
+        <anyAttribute namespace="##other" processContents="lax"/>
+    </complexType>
+    <element name="OrganizationName" type="md:localizedNameType"/>
+    <element name="OrganizationDisplayName" type="md:localizedNameType"/>
+    <element name="OrganizationURL" type="md:localizedURIType"/>
+    <element name="ContactPerson" type="md:ContactType"/>
+    <complexType name="ContactType">
+        <sequence>
+            <element ref="md:Extensions" minOccurs="0"/>
+            <element ref="md:Company" minOccurs="0"/>
+            <element ref="md:GivenName" minOccurs="0"/>
+            <element ref="md:SurName" minOccurs="0"/>
+            <element ref="md:EmailAddress" minOccurs="0" maxOccurs="unbounded"/>
+            <element ref="md:TelephoneNumber" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+        <attribute name="contactType" type="md:ContactTypeType" use="required"/>
+        <anyAttribute namespace="##other" processContents="lax"/>
+    </complexType>
+    <element name="Company" type="saml:string"/>
+    <element name="GivenName" type="saml:string"/>
+    <element name="SurName" type="saml:string"/>
+    <element name="EmailAddress" type="saml:anyURI"/>
+    <element name="TelephoneNumber" type="saml:string"/>
+    <simpleType name="ContactTypeType">
+        <restriction base="string">
+            <enumeration value="technical"/>
+            <enumeration value="support"/>
+            <enumeration value="administrative"/>
+            <enumeration value="billing"/>
+            <enumeration value="other"/>
+        </restriction>
+    </simpleType>
+
+    <element name="AdditionalMetadataLocation" type="md:AdditionalMetadataLocationType"/>
+    <complexType name="AdditionalMetadataLocationType">
+        <simpleContent>
+            <extension base="saml:anyURI">
+                <attribute name="namespace" type="saml:anyURI" use="required"/>
+            </extension>
+        </simpleContent>
+    </complexType>
+
+    <element name="RoleDescriptor" type="md:RoleDescriptorType"/>
+    <complexType name="RoleDescriptorType" abstract="true">
+        <sequence>
+            <element ref="ds:Signature" minOccurs="0"/>
+            <element ref="md:Extensions" minOccurs="0"/>
+            <element ref="md:KeyDescriptor" minOccurs="0" maxOccurs="unbounded"/>
+            <element ref="md:Organization" minOccurs="0"/>
+            <element ref="md:ContactPerson" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+        <attribute name="ID" type="ID" use="optional"/>
+        <attribute name="validUntil" type="dateTime" use="optional"/>
+        <attribute name="cacheDuration" type="duration" use="optional"/>
+        <attribute name="protocolSupportEnumeration" type="md:anyURIListType" use="required"/>
+        <attribute name="errorURL" type="anyURI" use="optional"/>
+        <anyAttribute namespace="##other" processContents="lax"/>
+    </complexType>
+    <simpleType name="anyURIListType">
+        <list itemType="saml:anyURI"/>
+    </simpleType>
+
+    <element name="KeyDescriptor" type="md:KeyDescriptorType"/>
+    <complexType name="KeyDescriptorType">
+        <sequence>
+            <element ref="ds:KeyInfo"/>
+            <element ref="md:EncryptionMethod" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+        <attribute name="use" type="md:KeyTypes" use="optional"/>
+    </complexType>
+    <simpleType name="KeyTypes">
+        <restriction base="string">
+            <enumeration value="encryption"/>
+            <enumeration value="signing"/>
+        </restriction>
+    </simpleType>
+    <element name="EncryptionMethod" type="xenc:EncryptionMethodType"/>
+    
+    <complexType name="SSODescriptorType" abstract="true">
+        <complexContent>
+            <extension base="md:RoleDescriptorType">
+                <sequence>
+                    <element ref="md:ArtifactResolutionService" minOccurs="0" maxOccurs="unbounded"/>
+                    <element ref="md:SingleLogoutService" minOccurs="0" maxOccurs="unbounded"/>
+                    <element ref="md:ManageNameIDService" minOccurs="0" maxOccurs="unbounded"/>
+                    <element ref="md:NameIDFormat" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="ArtifactResolutionService" type="md:IndexedEndpointType"/>
+    <element name="SingleLogoutService" type="md:EndpointType"/>
+    <element name="ManageNameIDService" type="md:EndpointType"/>
+    <element name="NameIDFormat" type="saml:anyURI"/>
+
+    <element name="IDPSSODescriptor" type="md:IDPSSODescriptorType"/>
+    <complexType name="IDPSSODescriptorType">
+        <complexContent>
+            <extension base="md:SSODescriptorType">
+                <sequence>
+                    <element ref="md:SingleSignOnService" maxOccurs="unbounded"/>
+                    <element ref="md:NameIDMappingService" minOccurs="0" maxOccurs="unbounded"/>
+                    <element ref="md:AssertionIDRequestService" minOccurs="0" maxOccurs="unbounded"/>
+                    <element ref="md:AttributeProfile" minOccurs="0" maxOccurs="unbounded"/>
+                    <element ref="saml:Attribute" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+                <attribute name="WantAuthnRequestsSigned" type="boolean" use="optional"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="SingleSignOnService" type="md:EndpointType"/>
+    <element name="NameIDMappingService" type="md:EndpointType"/>
+    <element name="AssertionIDRequestService" type="md:EndpointType"/>
+    <element name="AttributeProfile" type="saml:anyURI"/>
+    
+    <element name="SPSSODescriptor" type="md:SPSSODescriptorType"/>
+    <complexType name="SPSSODescriptorType">
+        <complexContent>
+            <extension base="md:SSODescriptorType">
+                <sequence>
+                    <element ref="md:AssertionConsumerService" maxOccurs="unbounded"/>
+                    <element ref="md:AttributeConsumingService" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+                <attribute name="AuthnRequestsSigned" type="boolean" use="optional"/>
+                <attribute name="WantAssertionsSigned" type="boolean" use="optional"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="AssertionConsumerService" type="md:IndexedEndpointType"/>
+    <element name="AttributeConsumingService" type="md:AttributeConsumingServiceType"/>
+    <complexType name="AttributeConsumingServiceType">
+        <sequence>
+            <element ref="md:ServiceName" maxOccurs="unbounded"/>
+            <element ref="md:ServiceDescription" minOccurs="0" maxOccurs="unbounded"/>
+            <element ref="md:RequestedAttribute" maxOccurs="unbounded"/>
+        </sequence>
+        <attribute name="index" type="unsignedShort" use="required"/>
+        <attribute name="isDefault" type="boolean" use="optional"/>
+    </complexType>
+    <element name="ServiceName" type="md:localizedNameType"/>
+    <element name="ServiceDescription" type="md:localizedNameType"/>
+    <element name="RequestedAttribute" type="md:RequestedAttributeType"/>
+    <complexType name="RequestedAttributeType">
+        <complexContent>
+            <extension base="saml:AttributeType">
+                <attribute name="isRequired" type="boolean" use="optional"/>
+            </extension>
+        </complexContent>
+    </complexType>
+  
+    <element name="AuthnAuthorityDescriptor" type="md:AuthnAuthorityDescriptorType"/>
+    <complexType name="AuthnAuthorityDescriptorType">
+        <complexContent>
+            <extension base="md:RoleDescriptorType">
+                <sequence>
+                    <element ref="md:AuthnQueryService" maxOccurs="unbounded"/>
+                    <element ref="md:AssertionIDRequestService" minOccurs="0" maxOccurs="unbounded"/>
+                    <element ref="md:NameIDFormat" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="AuthnQueryService" type="md:EndpointType"/>
+
+    <element name="PDPDescriptor" type="md:PDPDescriptorType"/>
+    <complexType name="PDPDescriptorType">
+        <complexContent>
+            <extension base="md:RoleDescriptorType">
+                <sequence>
+                    <element ref="md:AuthzService" maxOccurs="unbounded"/>
+                    <element ref="md:AssertionIDRequestService" minOccurs="0" maxOccurs="unbounded"/>
+                    <element ref="md:NameIDFormat" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="AuthzService" type="md:EndpointType"/>
+
+    <element name="AttributeAuthorityDescriptor" type="md:AttributeAuthorityDescriptorType"/>
+    <complexType name="AttributeAuthorityDescriptorType">
+        <complexContent>
+            <extension base="md:RoleDescriptorType">
+                <sequence>
+                    <element ref="md:AttributeService" maxOccurs="unbounded"/>
+                    <element ref="md:AssertionIDRequestService" minOccurs="0" maxOccurs="unbounded"/>
+                    <element ref="md:NameIDFormat" minOccurs="0" maxOccurs="unbounded"/>
+                    <element ref="md:AttributeProfile" minOccurs="0" maxOccurs="unbounded"/>
+                    <element ref="saml:Attribute" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="AttributeService" type="md:EndpointType"/>
+   
+    <element name="AffiliationDescriptor" type="md:AffiliationDescriptorType"/>
+    <complexType name="AffiliationDescriptorType">
+        <sequence>
+            <element ref="ds:Signature" minOccurs="0"/>
+            <element ref="md:Extensions" minOccurs="0"/>
+            <element ref="md:AffiliateMember" maxOccurs="unbounded"/>
+            <element ref="md:KeyDescriptor" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+        <attribute name="affiliationOwnerID" type="md:entityIDType" use="required"/>
+        <attribute name="validUntil" type="dateTime" use="optional"/>
+        <attribute name="cacheDuration" type="duration" use="optional"/>
+        <attribute name="ID" type="ID" use="optional"/>
+        <anyAttribute namespace="##other" processContents="lax"/>
+    </complexType>
+    <element name="AffiliateMember" type="md:entityIDType"/>
+</schema>
diff --git a/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-protocol-2.1.xsd b/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-protocol-2.1.xsd
new file mode 100644
index 000000000..db3dbd118
--- /dev/null
+++ b/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-protocol-2.1.xsd
@@ -0,0 +1,290 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" targetNamespace="urn:oasis:names:tc:SAML:2.0:protocol" elementFormDefault="unqualified" attributeFormDefault="unqualified" blockDefault="substitution" version="2.1">
+        
+    <import namespace="urn:oasis:names:tc:SAML:2.0:assertion" schemaLocation="saml-schema-assertion-2.1.xsd"/>
+    <import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd"/>
+        
+    <annotation>
+        <documentation>
+            Document identifier: saml-schema-protocol-2.1
+            Revision history:
+            V1.0 (November, 2002): Initial Standard Schema.
+            V1.1 (September, 2003): Updates within the same V1.0 namespace.
+            V2.0 (March, 2005): New protocol schema based in a SAML V2.0 namespace.
+            V2.1 (June 2020): Private Shibboleth version to tighten string and anyURI minLength.
+        </documentation>
+    </annotation>
+    <complexType name="RequestAbstractType" abstract="true">
+        <sequence>
+            <element ref="saml:Issuer" minOccurs="0"/>
+            <element ref="ds:Signature" minOccurs="0"/>
+            <element ref="samlp:Extensions" minOccurs="0"/>
+        </sequence>
+        <attribute name="ID" type="ID" use="required"/>
+        <attribute name="Version" type="saml:string" use="required"/>
+        <attribute name="IssueInstant" type="dateTime" use="required"/>
+        <attribute name="Destination" type="saml:anyURI" use="optional"/>
+        <attribute name="Consent" type="saml:anyURI" use="optional"/>
+    </complexType>
+    <element name="Extensions" type="samlp:ExtensionsType"/>
+    <complexType name="ExtensionsType">
+        <sequence>
+            <any namespace="##other" processContents="lax" maxOccurs="unbounded"/>
+        </sequence>
+    </complexType>
+    <complexType name="StatusResponseType">
+        <sequence>
+            <element ref="saml:Issuer" minOccurs="0"/>
+            <element ref="ds:Signature" minOccurs="0"/>
+            <element ref="samlp:Extensions" minOccurs="0"/>
+            <element ref="samlp:Status"/>
+        </sequence>
+        <attribute name="ID" type="ID" use="required"/>
+        <attribute name="InResponseTo" type="NCName" use="optional"/>
+        <attribute name="Version" type="saml:string" use="required"/>
+        <attribute name="IssueInstant" type="dateTime" use="required"/>
+        <attribute name="Destination" type="saml:anyURI" use="optional"/>
+        <attribute name="Consent" type="saml:anyURI" use="optional"/>
+    </complexType>
+    <element name="Status" type="samlp:StatusType"/>
+    <complexType name="StatusType">
+        <sequence>
+            <element ref="samlp:StatusCode"/>
+            <element ref="samlp:StatusMessage" minOccurs="0"/>
+            <element ref="samlp:StatusDetail" minOccurs="0"/>
+        </sequence>
+    </complexType>
+    <element name="StatusCode" type="samlp:StatusCodeType"/>
+    <complexType name="StatusCodeType">
+        <sequence>
+            <element ref="samlp:StatusCode" minOccurs="0"/>
+        </sequence>
+        <attribute name="Value" type="saml:anyURI" use="required"/>
+    </complexType>
+    <element name="StatusMessage" type="saml:string"/>
+    <element name="StatusDetail" type="samlp:StatusDetailType"/>
+    <complexType name="StatusDetailType">
+        <sequence>
+            <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+    </complexType>
+    <element name="AssertionIDRequest" type="samlp:AssertionIDRequestType"/>
+    <complexType name="AssertionIDRequestType">
+        <complexContent>
+            <extension base="samlp:RequestAbstractType">
+                <sequence>
+                    <element ref="saml:AssertionIDRef" maxOccurs="unbounded"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="SubjectQuery" type="samlp:SubjectQueryAbstractType"/>
+    <complexType name="SubjectQueryAbstractType" abstract="true">
+        <complexContent>
+            <extension base="samlp:RequestAbstractType">
+                <sequence>
+                    <element ref="saml:Subject"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="AuthnQuery" type="samlp:AuthnQueryType"/>
+    <complexType name="AuthnQueryType">
+        <complexContent>
+            <extension base="samlp:SubjectQueryAbstractType">
+                <sequence>
+                    <element ref="samlp:RequestedAuthnContext" minOccurs="0"/>
+                </sequence>
+                <attribute name="SessionIndex" type="saml:string" use="optional"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="RequestedAuthnContext" type="samlp:RequestedAuthnContextType"/>
+    <complexType name="RequestedAuthnContextType">
+        <choice>
+            <element ref="saml:AuthnContextClassRef" maxOccurs="unbounded"/>
+            <element ref="saml:AuthnContextDeclRef" maxOccurs="unbounded"/>
+        </choice>
+        <attribute name="Comparison" type="samlp:AuthnContextComparisonType" use="optional"/>
+    </complexType>
+    <simpleType name="AuthnContextComparisonType">
+        <restriction base="string">
+            <enumeration value="exact"/>
+            <enumeration value="minimum"/>
+            <enumeration value="maximum"/>
+            <enumeration value="better"/>
+        </restriction>
+    </simpleType>
+    <element name="AttributeQuery" type="samlp:AttributeQueryType"/>
+    <complexType name="AttributeQueryType">
+        <complexContent>
+            <extension base="samlp:SubjectQueryAbstractType">
+                <sequence>
+                    <element ref="saml:Attribute" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="AuthzDecisionQuery" type="samlp:AuthzDecisionQueryType"/>
+    <complexType name="AuthzDecisionQueryType">
+        <complexContent>
+            <extension base="samlp:SubjectQueryAbstractType">
+                <sequence>
+                    <element ref="saml:Action" maxOccurs="unbounded"/>
+                    <element ref="saml:Evidence" minOccurs="0"/>
+                </sequence>
+                <attribute name="Resource" type="saml:anyURI" use="required"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="AuthnRequest" type="samlp:AuthnRequestType"/>
+    <complexType name="AuthnRequestType">
+        <complexContent>
+            <extension base="samlp:RequestAbstractType">
+                <sequence>
+                    <element ref="saml:Subject" minOccurs="0"/>
+                    <element ref="samlp:NameIDPolicy" minOccurs="0"/>
+                    <element ref="saml:Conditions" minOccurs="0"/>
+                    <element ref="samlp:RequestedAuthnContext" minOccurs="0"/>
+                    <element ref="samlp:Scoping" minOccurs="0"/>
+                </sequence>
+                <attribute name="ForceAuthn" type="boolean" use="optional"/>
+                <attribute name="IsPassive" type="boolean" use="optional"/>
+                <attribute name="ProtocolBinding" type="saml:anyURI" use="optional"/>
+                <attribute name="AssertionConsumerServiceIndex" type="unsignedShort" use="optional"/>
+                <attribute name="AssertionConsumerServiceURL" type="saml:anyURI" use="optional"/>
+                <attribute name="AttributeConsumingServiceIndex" type="unsignedShort" use="optional"/>
+                <attribute name="ProviderName" type="saml:string" use="optional"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="NameIDPolicy" type="samlp:NameIDPolicyType"/>
+    <complexType name="NameIDPolicyType">
+        <attribute name="Format" type="saml:anyURI" use="optional"/>
+        <attribute name="SPNameQualifier" type="saml:string" use="optional"/>
+        <attribute name="AllowCreate" type="boolean" use="optional"/>
+    </complexType>
+    <element name="Scoping" type="samlp:ScopingType"/>
+    <complexType name="ScopingType">
+        <sequence>
+            <element ref="samlp:IDPList" minOccurs="0"/>
+            <element ref="samlp:RequesterID" minOccurs="0" maxOccurs="unbounded"/>
+        </sequence>
+        <attribute name="ProxyCount" type="nonNegativeInteger" use="optional"/>
+    </complexType>
+    <element name="RequesterID" type="saml:anyURI"/>
+    <element name="IDPList" type="samlp:IDPListType"/>
+    <complexType name="IDPListType">
+        <sequence>
+            <element ref="samlp:IDPEntry" maxOccurs="unbounded"/>
+            <element ref="samlp:GetComplete" minOccurs="0"/>
+        </sequence>
+    </complexType>
+    <element name="IDPEntry" type="samlp:IDPEntryType"/>
+    <complexType name="IDPEntryType">
+        <attribute name="ProviderID" type="saml:anyURI" use="required"/>
+        <attribute name="Name" type="saml:string" use="optional"/>
+        <attribute name="Loc" type="saml:anyURI" use="optional"/>
+    </complexType>
+    <element name="GetComplete" type="saml:anyURI"/>
+    <element name="Response" type="samlp:ResponseType"/>
+    <complexType name="ResponseType">
+        <complexContent>
+            <extension base="samlp:StatusResponseType">
+                <choice minOccurs="0" maxOccurs="unbounded">
+                    <element ref="saml:Assertion"/>
+                    <element ref="saml:EncryptedAssertion"/>
+                </choice>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="ArtifactResolve" type="samlp:ArtifactResolveType"/>
+    <complexType name="ArtifactResolveType">
+        <complexContent>
+            <extension base="samlp:RequestAbstractType">
+                <sequence>
+                    <element ref="samlp:Artifact"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="Artifact" type="saml:string"/>
+    <element name="ArtifactResponse" type="samlp:ArtifactResponseType"/>
+    <complexType name="ArtifactResponseType">
+        <complexContent>
+            <extension base="samlp:StatusResponseType">
+                <sequence>
+                    <any namespace="##any" processContents="lax" minOccurs="0"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="ManageNameIDRequest" type="samlp:ManageNameIDRequestType"/>
+    <complexType name="ManageNameIDRequestType">
+        <complexContent>
+            <extension base="samlp:RequestAbstractType">
+                <sequence>
+                    <choice>
+                        <element ref="saml:NameID"/>
+                        <element ref="saml:EncryptedID"/>
+                    </choice>
+                    <choice>
+                        <element ref="samlp:NewID"/>
+                        <element ref="samlp:NewEncryptedID"/>
+                        <element ref="samlp:Terminate"/>
+                    </choice>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="NewID" type="saml:string"/>
+    <element name="NewEncryptedID" type="saml:EncryptedElementType"/>
+    <element name="Terminate" type="samlp:TerminateType"/>
+    <complexType name="TerminateType"/>
+    <element name="ManageNameIDResponse" type="samlp:StatusResponseType"/>
+    <element name="LogoutRequest" type="samlp:LogoutRequestType"/>
+    <complexType name="LogoutRequestType">
+        <complexContent>
+            <extension base="samlp:RequestAbstractType">
+                <sequence>
+                    <choice>
+                        <element ref="saml:BaseID"/>
+                        <element ref="saml:NameID"/>
+                        <element ref="saml:EncryptedID"/>
+                    </choice>
+                    <element ref="samlp:SessionIndex" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+                <attribute name="Reason" type="saml:string" use="optional"/>
+                <attribute name="NotOnOrAfter" type="dateTime" use="optional"/>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="SessionIndex" type="saml:string"/>
+    <element name="LogoutResponse" type="samlp:StatusResponseType"/>
+    <element name="NameIDMappingRequest" type="samlp:NameIDMappingRequestType"/>
+    <complexType name="NameIDMappingRequestType">
+        <complexContent>
+            <extension base="samlp:RequestAbstractType">
+                <sequence>
+                    <choice>
+                        <element ref="saml:BaseID"/>
+                        <element ref="saml:NameID"/>
+                        <element ref="saml:EncryptedID"/>
+                    </choice>
+                    <element ref="samlp:NameIDPolicy"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+    <element name="NameIDMappingResponse" type="samlp:NameIDMappingResponseType"/>
+    <complexType name="NameIDMappingResponseType">
+        <complexContent>
+            <extension base="samlp:StatusResponseType">
+                <choice>
+                    <element ref="saml:NameID"/>
+                    <element ref="saml:EncryptedID"/>
+                </choice>
+            </extension>
+        </complexContent>
+    </complexType>
+</schema>
diff --git a/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-x500-2.1.xsd b/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-x500-2.1.xsd
new file mode 100644
index 000000000..fbd90d867
--- /dev/null
+++ b/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-x500-2.1.xsd
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" targetNamespace="urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500" elementFormDefault="unqualified" attributeFormDefault="unqualified" blockDefault="substitution" version="2.0">
+
+    <annotation>
+        <documentation>
+            Document identifier: saml-schema-x500-2.1 
+            Revision history:
+            V2.0 (March, 2005):
+                Custom schema for X.500 attribute profile, first published in SAML 2.0.
+            V2.1 (June 2020):
+                Private Shibboleth version to tighten string and anyURI minLength.
+        </documentation>
+    </annotation>
+
+    <import namespace="urn:oasis:names:tc:SAML:2.0:assertion" schemaLocation="saml-schema-assertion-2.1.xsd"/>
+
+    <attribute name="Encoding" type="saml:string"/>
+</schema>
diff --git a/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-xacml-2.1.xsd b/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-xacml-2.1.xsd
new file mode 100644
index 000000000..bc6518639
--- /dev/null
+++ b/opensaml-saml-api/src/main/resources/schema/strict/saml-schema-xacml-2.1.xsd
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" targetNamespace="urn:oasis:names:tc:SAML:2.0:profiles:attribute:XACML" elementFormDefault="unqualified" attributeFormDefault="unqualified" blockDefault="substitution" version="2.0">
+
+    <annotation>
+        <documentation>
+            Document identifier: saml-schema-xacml-2.1 
+            Revision history:
+            V2.0 (March, 2005):
+                Custom schema for XACML attribute profile, first published in SAML 2.0.
+            V2.1 (June 2020):
+                Private Shibboleth version to tighten string and anyURI minLength.
+        </documentation>
+    </annotation>
+
+    <import namespace="urn:oasis:names:tc:SAML:2.0:assertion" schemaLocation="saml-schema-assertion-2.1.xsd"/>
+
+    <attribute name="DataType" type="saml:anyURI"/>
+
+</schema>
diff --git a/opensaml-saml-api/src/main/resources/schema/strict/sstc-saml-metadata-algsupport-v1.1.xsd b/opensaml-saml-api/src/main/resources/schema/strict/sstc-saml-metadata-algsupport-v1.1.xsd
new file mode 100644
index 000000000..06eeb808a
--- /dev/null
+++ b/opensaml-saml-api/src/main/resources/schema/strict/sstc-saml-metadata-algsupport-v1.1.xsd
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+
+    SAML v2.0 Metadata Profile for Algorithm Support Version 1.0
+    Committee Specification 01
+    21 February 2011
+    Copyright (c) OASIS Open 2011.   All rights reserved.
+    Source: http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-metadata-algsupport-v1.0-cs01.xsd
+
+-->
+
+<schema 
+  targetNamespace="urn:oasis:names:tc:SAML:metadata:algsupport"
+  xmlns="http://www.w3.org/2001/XMLSchema"
+  xmlns:alg="urn:oasis:names:tc:SAML:metadata:algsupport"
+  xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
+  elementFormDefault="unqualified"
+  attributeFormDefault="unqualified"
+  blockDefault="substitution"
+  version="1.1">
+
+  <annotation>
+    <documentation>
+      Document title: Metadata Extension Schema for SAML V2.0 Metadata Profile for Algorithm Support Version 1.0
+      Document identifier: sstc-saml-metadata-algsupport-v1.1.xsd
+      Revision history:
+      V1.0 (June 2010):
+        Initial version.
+      (October 2010):
+        Add processContents="lax" to wildcards.
+      (June 2020):
+        Private Shibboleth version to tighten string and anyURI minLength.
+    </documentation>
+  </annotation>
+
+  <import namespace="urn:oasis:names:tc:SAML:2.0:assertion" schemaLocation="saml-schema-assertion-2.1.xsd"/>
+
+  <element name="DigestMethod" type="alg:DigestMethodType"/>
+  <complexType name="DigestMethodType">
+    <sequence>
+      <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+    </sequence>
+    <attribute name="Algorithm" type="saml:anyURI" use="required"/>
+  </complexType>
+
+  <element name="SigningMethod" type="alg:SigningMethodType"/>
+  <complexType name="SigningMethodType">
+    <sequence>
+      <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+    </sequence>
+    <attribute name="Algorithm" type="saml:anyURI" use="required"/>
+    <attribute name="MinKeySize" type="positiveInteger"/>
+    <attribute name="MaxKeySize" type="positiveInteger"/>
+  </complexType>
+
+</schema>
+
diff --git a/opensaml-saml-api/src/main/resources/schema/strict/sstc-saml-metadata-ext-query.xsd b/opensaml-saml-api/src/main/resources/schema/strict/sstc-saml-metadata-ext-query.xsd
new file mode 100644
index 000000000..af9cc79fb
--- /dev/null
+++ b/opensaml-saml-api/src/main/resources/schema/strict/sstc-saml-metadata-ext-query.xsd
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:query="urn:oasis:names:tc:SAML:metadata:ext:query" targetNamespace="urn:oasis:names:tc:SAML:metadata:ext:query" elementFormDefault="unqualified" attributeFormDefault="unqualified" blockDefault="substitution" version="2.1">
+
+    <annotation>
+        <documentation>
+            Document title: SAML Metadata Extension Schema for Query Requester
+            Document identifier: sstc-saml-metadata-ext-query.xsd Location:
+            http://www.oasis-open.org/committees/documents.php?wg_abbrev=security
+            Revision history:
+            V2.0 (February 2006):
+                Initial version.
+            V2.1 (June 2020):
+                Private Shibboleth version to tighten string and anyURI minLength.
+        </documentation>
+    </annotation>
+
+    <import namespace="urn:oasis:names:tc:SAML:2.0:assertion" schemaLocation="saml-schema-assertion-2.1.xsd"/>
+    <import namespace="urn:oasis:names:tc:SAML:2.0:metadata" schemaLocation="saml-schema-metadata-2.1.xsd"/>
+
+    <complexType name="QueryDescriptorType" abstract="true">
+        <complexContent>
+            <extension base="md:RoleDescriptorType">
+                <sequence>
+                    <element ref="md:NameIDFormat" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+                <attribute name="WantAssertionsSigned" type="boolean" use="optional"/>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <complexType name="AuthnQueryDescriptorType">
+        <complexContent>
+            <extension base="query:QueryDescriptorType"/>
+        </complexContent>
+    </complexType>
+
+    <complexType name="AttributeQueryDescriptorType">
+        <complexContent>
+            <extension base="query:QueryDescriptorType">
+                <sequence>
+                    <element ref="md:AttributeConsumingService" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+
+    <element name="ActionNamespace" type="saml:anyURI"/>
+
+    <complexType name="AuthzDecisionQueryDescriptorType">
+        <complexContent>
+            <extension base="query:QueryDescriptorType">
+                <sequence>
+                    <element ref="query:ActionNamespace" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+            </extension>
+        </complexContent>
+    </complexType>
+
+</schema>
diff --git a/opensaml-saml-api/src/main/resources/schema/strict/sstc-saml-metadata-ui-v1.1.xsd b/opensaml-saml-api/src/main/resources/schema/strict/sstc-saml-metadata-ui-v1.1.xsd
new file mode 100644
index 000000000..232887e46
--- /dev/null
+++ b/opensaml-saml-api/src/main/resources/schema/strict/sstc-saml-metadata-ui-v1.1.xsd
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" targetNamespace="urn:oasis:names:tc:SAML:metadata:ui" elementFormDefault="unqualified" attributeFormDefault="unqualified" blockDefault="substitution" version="1.1">
+
+  <annotation>
+    <documentation>
+      Document title: Metadata Extension Schema for SAML V2.0 Metadata Extensions for Login and Discovery User Interface Version 1.0
+      Document identifier: sstc-saml-metadata-ui-v1.1.xsd
+      Revision history:
+      01 November 2010
+        Changed filename.
+      September 2010:
+        Initial version.
+      Jun 2020:
+        Private Shibboleth version to tighten string and anyURI minLength.
+    </documentation>
+  </annotation>
+
+  <import namespace="urn:oasis:names:tc:SAML:2.0:assertion" schemaLocation="saml-schema-assertion-2.1.xsd"/>
+  <import namespace="urn:oasis:names:tc:SAML:2.0:metadata" schemaLocation="saml-schema-metadata-2.1.xsd"/>
+  <import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+
+  <element name="UIInfo" type="mdui:UIInfoType"/>
+  <complexType name="UIInfoType">
+    <choice minOccurs="0" maxOccurs="unbounded">
+      <element ref="mdui:DisplayName"/>
+      <element ref="mdui:Description"/>
+      <element ref="mdui:Keywords"/>
+      <element ref="mdui:Logo"/>
+      <element ref="mdui:InformationURL"/>
+      <element ref="mdui:PrivacyStatementURL"/>
+      <any namespace="##other" processContents="lax"/>
+    </choice>
+  </complexType>
+
+  <element name="DisplayName" type="md:localizedNameType"/>
+  <element name="Description" type="md:localizedNameType"/>
+  <element name="InformationURL" type="md:localizedURIType"/>
+  <element name="PrivacyStatementURL" type="md:localizedURIType"/>
+
+  <element name="Keywords" type="mdui:KeywordsType"/>
+  <complexType name="KeywordsType">
+    <simpleContent>
+      <extension base="mdui:listOfStrings">
+        <attribute ref="xml:lang" use="required"/>
+      </extension>
+    </simpleContent>
+  </complexType>
+  
+  <simpleType name="listOfStrings">
+    <list itemType="saml:string"/>
+  </simpleType>
+
+  <element name="Logo" type="mdui:LogoType"/>
+  <complexType name="LogoType">
+    <simpleContent>
+      <extension base="saml:anyURI">
+        <attribute name="height" type="positiveInteger" use="required"/>
+        <attribute name="width" type="positiveInteger" use="required"/>
+        <attribute ref="xml:lang"/>
+      </extension>
+    </simpleContent>
+  </complexType>
+
+  <element name="DiscoHints" type="mdui:DiscoHintsType"/>
+  <complexType name="DiscoHintsType">
+    <choice minOccurs="0" maxOccurs="unbounded">
+      <element ref="mdui:IPHint"/>
+      <element ref="mdui:DomainHint"/>
+      <element ref="mdui:GeolocationHint"/>
+      <any namespace="##other" processContents="lax"/>
+    </choice>
+  </complexType>
+
+  <element name="IPHint" type="saml:string"/>
+  <element name="DomainHint" type="saml:string"/>	
+  <element name="GeolocationHint" type="saml:anyURI"/>
+
+</schema>
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SchemaValidationFilterTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SchemaValidationFilterTest.java
index 87838871f..c802c50a8 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SchemaValidationFilterTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SchemaValidationFilterTest.java
@@ -17,42 +17,51 @@
 
 package org.opensaml.saml.metadata.resolver.filter.impl;
 
-import org.apache.http.client.params.AllClientPNames;
-import org.apache.http.impl.client.DefaultHttpClient;
 import org.opensaml.core.xml.XMLObjectBaseTestCase;
 import org.opensaml.saml.common.xml.SAMLSchemaBuilder;
 import org.opensaml.saml.common.xml.SAMLSchemaBuilder.SAML1Version;
-import org.opensaml.saml.metadata.resolver.impl.HTTPMetadataResolver;
-import org.testng.annotations.BeforeMethod;
+import org.opensaml.saml.metadata.resolver.impl.ResourceBackedMetadataResolver;
+import org.springframework.core.io.ClassPathResource;
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import net.shibboleth.utilities.java.support.repository.RepositorySupport;
+import net.shibboleth.ext.spring.resource.ResourceHelper;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
 
 /**
  * Unit tests for {@link SchemaValidationFilter}.
  */
- at SuppressWarnings("deprecation")
 public class SchemaValidationFilterTest extends XMLObjectBaseTestCase {
-    
-    private DefaultHttpClient httpClient;
-
-    /** URL to InCommon metadata. */
-    private String inCommonMDURL;
-
-    @BeforeMethod
-    protected void setUp() throws Exception {
-        httpClient = new DefaultHttpClient();
-        httpClient.getParams().setIntParameter(AllClientPNames.CONNECTION_TIMEOUT, 1000 * 5);
-        
-        inCommonMDURL = RepositorySupport.buildHTTPResourceURL("java-opensaml", "opensaml-saml-impl/src/test/resources/org/opensaml/saml/saml2/metadata/InCommon-metadata.xml", false);
-    }
 
     @Test
-    public void test() throws Exception {
-        HTTPMetadataResolver metadataProvider = new HTTPMetadataResolver(httpClient, inCommonMDURL);
+    public void testValid() throws Exception {
+        final ResourceBackedMetadataResolver metadataProvider = new ResourceBackedMetadataResolver(
+                ResourceHelper.of(new ClassPathResource("org/opensaml/saml/saml2/metadata/valid-metadata.xml")));
         metadataProvider.setParserPool(parserPool);
         metadataProvider.setId("test");
         metadataProvider.setMetadataFilter(new SchemaValidationFilter(new SAMLSchemaBuilder(SAML1Version.SAML_11)));
         metadataProvider.initialize();
     }
+    
+    @Test
+    public void testStrict() throws Exception {
+        final ResourceBackedMetadataResolver metadataProvider = new ResourceBackedMetadataResolver(
+                ResourceHelper.of(new ClassPathResource("org/opensaml/saml/saml2/metadata/valid-metadata.xml")));
+        metadataProvider.setParserPool(parserPool);
+        metadataProvider.setId("test");
+        metadataProvider.setMetadataFilter(new SchemaValidationFilter(new SAMLSchemaBuilder(SAML1Version.SAML_11, true)));
+        metadataProvider.initialize();
+    }
+    
+    @Test(expectedExceptions=ComponentInitializationException.class)
+    public void testStrictInvalid() throws Exception {
+        final ResourceBackedMetadataResolver metadataProvider = new ResourceBackedMetadataResolver(
+                ResourceHelper.of(new ClassPathResource("org/opensaml/saml/saml2/metadata/invalid-metadata.xml")));
+        metadataProvider.setParserPool(parserPool);
+        metadataProvider.setId("test");
+        metadataProvider.setMetadataFilter(new SchemaValidationFilter(new SAMLSchemaBuilder(SAML1Version.SAML_11, true)));
+        metadataProvider.initialize();
+        Assert.fail("Should have raised schema validation error");
+    }
+
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/test/resources/org/opensaml/saml/saml2/metadata/invalid-metadata.xml b/opensaml-saml-impl/src/test/resources/org/opensaml/saml/saml2/metadata/invalid-metadata.xml
new file mode 100644
index 000000000..6222a129c
--- /dev/null
+++ b/opensaml-saml-impl/src/test/resources/org/opensaml/saml/saml2/metadata/invalid-metadata.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="urn:mace:incommon" xsi:schemaLocation="urn:oasis:names:tc:SAML:2.0:metadata sstc-saml-schema-metadata-2.0.xsd urn:mace:shibboleth:metadata:1.0 shibboleth-metadata-1.0.xsd http://www.w3.org/2000/09/xmldsig# xmldsig-core-schema.xsd">
+  <Extensions>
+    <shibmd:KeyAuthority xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" VerifyDepth="5">
+      <!-- InCommon CA -->
+      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+        <ds:X509Data>
+          <ds:X509Certificate>
+MIIFmjCCBIKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJVUzEc
+MBoGA1UEChMTSW5Db21tb24gRmVkZXJhdGlvbjEpMCcGA1UEAxMgSW5Db21tb24g
+Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwMzMwMjAzNDAwWhcNMTQwMzI5
+MjAzNDAwWjBWMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTSW5Db21tb24gRmVkZXJh
+dGlvbjEpMCcGA1UEAxMgSW5Db21tb24gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRGjKsUM2QAupLAaWx82/C
+WPalKjKFY8UPmz0T3gf7tJPztTy1Zq8pD0WFRLcQeSBKZGCu8upe8X966b6TZ5yu
+oUDA754If0DWismuHNoMgRR/l0UvZmPWDGRWd3NBTB8/soLA4EbqFf5Xq8MOJKhP
+tzcDR33gtaAb3oilZ+ZTpnhTFFrn/qXrAKcSDBpuW2JRpi3xaF/hTPI097oUShOz
+D1Zj21UYLA6iSFVN+1wlfwilf2KFNK/+zbkCge6wgipZyXxaOAam6ncqmkxy+hy/
+OiJMmdB+6xkO0xXSBUUcqxJrOcUQhA1vntgb3q5zOJISXhC4RAReA0HyBp/wd0iD
+AgMBAAGjggJxMIICbTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
+BgNVHQ4EFgQUky3IYRitY+ObZbOd3Y2TuufKY0UwfgYDVR0jBHcwdYAUky3IYRit
+Y+ObZbOd3Y2TuufKY0WhWqRYMFYxCzAJBgNVBAYTAlVTMRwwGgYDVQQKExNJbkNv
+bW1vbiBGZWRlcmF0aW9uMSkwJwYDVQQDEyBJbkNvbW1vbiBDZXJ0aWZpY2F0aW9u
+IEF1dGhvcml0eYIBADCBugYIKwYBBQUHAQEEga0wgaowgacGCCsGAQUFBzAChoGa
+aHR0cDovL2luY29tbW9uY2ExLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvYnJpZGdl
+L2NlcnRzL2NhLWNlcnRzLnA3YgoJCUNBIElzc3VlcnMgLSBVUkk6aHR0cDovL2lu
+Y29tbW9uY2EyLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvYnJpZGdlL2NlcnRzL2Nh
+LWNlcnRzLnA3YjCBjQYDVR0fBIGFMIGCMD+gPaA7hjlodHRwOi8vaW5jb21tb25j
+cmwxLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvY3JsL2VlY3Jscy5jcmwwP6A9oDuG
+OWh0dHA6Ly9pbmNvbW1vbmNybDIuaW5jb21tb25mZWRlcmF0aW9uLm9yZy9jcmwv
+ZWVjcmxzLmNybDBeBgNVHSAEVzBVMFMGCysGAQQBriMBBAEBMEQwQgYIKwYBBQUH
+AgEWNmh0dHA6Ly9pbmNvbW1vbmNhLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvcHJh
+Y3RpY2VzLnBkZjANBgkqhkiG9w0BAQUFAAOCAQEAZfgKUPA+Ky+Ou/vclMlFTMlU
+GspfbNSdG/fmIq+E/Lv1d2c73Am1zGhOpxgdkM8SE+BPnXW2rl71/N8gaqwgBBxk
+pwn410siumxlDTwV3HoVFvCGWylNy9o8OE1LyTCqfo8PRwrMzhwcagDgD813BIyj
+uJg/JQz1LnHMocIW/JligloSIzF1O435/+ckfWXQsmBIhvV5TmA3ZrcycrI1cHGE
+ZqrCXL0FMZLSr+Vady/tFbVojqI8pSubSMxNkZectePTBjVj1Qeb4hmG8jRv/fwy
+1Iw6OFH8RKny8nQaO5mOe/fF/swEsMVU9TDpvLIgbhTwnP7Nhfotgaxf5wG8WA==
+          </ds:X509Certificate>
+        </ds:X509Data>
+      </ds:KeyInfo>
+    </shibmd:KeyAuthority>
+  </Extensions>
+<EntityDescriptor entityID="https://carmenwiki.osu.edu/shibboleth" xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
+  <Extensions xmlns:mdattr="urn:oasis:names:tc:SAML:metadata:attribute" xmlns:mdrpi="urn:oasis:names:tc:SAML:metadata:rpi">
+    <mdrpi:RegistrationInfo registrationAuthority="https://incommon.org"/>
+    <mdattr:EntityAttributes xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
+      <saml:Attribute Name="http://macedir.org/entity-category" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+        <saml:AttributeValue>http://id.incommon.org/category/research-and-scholarship</saml:AttributeValue>
+        <saml:AttributeValue>http://refeds.org/category/research-and-scholarship</saml:AttributeValue>
+        <saml:AttributeValue>http://id.incommon.org/category/registered-by-incommon</saml:AttributeValue>
+      </saml:Attribute>
+    </mdattr:EntityAttributes>
+  </Extensions>
+  <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:2.0:protocol">
+    <md:Extensions xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
+      <DiscoveryResponse xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://carmenwiki.osu.edu/Shibboleth.sso/Login" index="1"/>
+      <DiscoveryResponse xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://carmenwiki.it.ohio-state.edu/Shibboleth.sso/Login" index="2"/>
+      <DiscoveryResponse xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://carmenwiki.osu.edu/Shibboleth.sso/Clear" index="3"/>
+      <DiscoveryResponse xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://carmenwiki.it.ohio-state.edu/Shibboleth.sso/Clear" index="4"/>
+      <mdui:UIInfo xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui">
+        <mdui:DisplayName xml:lang="en">CarmenWiki</mdui:DisplayName>
+        <mdui:Description xml:lang="en">Enterprise Wiki Service at the Ohio State University.</mdui:Description>
+        <mdui:InformationURL xml:lang="en">https://ocio.osu.edu/services/view/carmenwiki-wiki-services</mdui:InformationURL>
+        <mdui:PrivacyStatementURL xml:lang="en">https://carmenwiki.osu.edu/x/jyLeAQ</mdui:PrivacyStatementURL>
+        <mdui:Logo height="85" width="141" xml:lang="en">https://carmenwiki.osu.edu/download/attachments/9666561/global.logo</mdui:Logo>
+      </mdui:UIInfo>
+    </md:Extensions>
+    <md:KeyDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
+      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+        <ds:X509Data>
+<!-- Serial No. 15149766524924023670, expires on Sat Jul  4 22:43:05 2020 GMT -->
+          <ds:X509Certificate>
+MIIDGzCCAgOgAwIBAgIJANI+yGM0M1N2MA0GCSqGSIb3DQEBBQUAMCcxJTAjBgNV
+BAMTHGx0Y2F3aWtpMDEuaXQub2hpby1zdGF0ZS5lZHUwHhcNMTAwNzA3MjI0MzA1
+WhcNMjAwNzA0MjI0MzA1WjAnMSUwIwYDVQQDExxsdGNhd2lraTAxLml0Lm9oaW8t
+c3RhdGUuZWR1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5fsEv25M
+r9wfa48qfjn8m40yB/lwimJ8dSnYw2erd/tfB+sPESw42Is5Lv2B3pI3mj9a0PT0
+Gf1VgUoQW0RCT6L4VOW50WsPFv/RKPfT/AIRl00dTCqb440PgotGbrK9ivZqlvkz
+lSGUKuFcg2gLj+CJlbMcwEneSwn0FE1xKEGpMDUk91lZH1XxmnIDDOQn1G5qul4q
+AbXITMpLi2MlsHAEXxnLrthFFas6zDrviTwHcqGXq9zJJkPHDcbu1qg6AUT7bRJr
+qszxxktSV6mFclkgLPpcVkigMR8RNVMQkWaaWSnfBkFy2iAe3xw3DNp7obtzgItY
+i9N8U6K5qorSkQIDAQABo0owSDAnBgNVHREEIDAeghxsdGNhd2lraTAxLml0Lm9o
+aW8tc3RhdGUuZWR1MB0GA1UdDgQWBBR32XnCliG78DdyTtZhyIQSHChtyjANBgkq
+hkiG9w0BAQUFAAOCAQEAVEweCxPElHGmam4Iv2QeJsGE7m4de7axp3epAJb7uVbN
+Z2P1S/s4GZQhmGsUoGoxwqca3wyQ+C1ZkpQJdyFl5s1tFc26D+Z0KTDo174GzO9i
+I9SeQ4YSp3FNhZqxn4xH3DULzzHwoVSwFr5irLPAVtrqK8H/rzBREhqOse2VSJ/1
+PkI+p7lUiElIzMiObLGjumF2fDOPkXOSMNyC4c5oCCJtcrip/BaLo6bqdqn3DKP8
+onMw/lHZQolyVsupuhGsSX13WVJ0uyGvuA7hiHnGEkpDmskUd3TsriyQAt47RZzY
+tTupO/NdWvz8SvXU1qIOk9CTQ0D2b2OOftfUW+FuAQ==
+          </ds:X509Certificate>
+        </ds:X509Data>
+      </ds:KeyInfo>
+    </md:KeyDescriptor>
+    <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="https://carmenwiki.osu.edu/Shibboleth.sso/SAML/POST" index="1"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" Location="https://carmenwiki.osu.edu/Shibboleth.sso/SAML/Artifact" index="2"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="https://carmenwiki.it.ohio-state.edu/Shibboleth.sso/SAML/POST" index="3"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" Location="https://carmenwiki.it.ohio-state.edu/Shibboleth.sso/SAML/Artifact" index="4"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://carmenwiki.osu.edu/Shibboleth.sso/SAML2/POST" index="5"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://carmenwiki.osu.edu/Shibboleth.sso/SAML2/Artifact" index="6"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://carmenwiki.it.ohio-state.edu/Shibboleth.sso/SAML2/POST" index="7"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://carmenwiki.it.ohio-state.edu/Shibboleth.sso/SAML2/Artifact" index="8"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://carmenwiki.osu.edu/Shibboleth.sso/SAML2/ECP" index="9"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://carmenwiki.it.ohio-state.edu/Shibboleth.sso/SAML2/ECP" index="10"/>
+    <AttributeConsumingService xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" index="1">
+      <ServiceName xml:lang="en">CarmenWiki</ServiceName>
+      <ServiceDescription xml:lang="en">Enterprise Wiki Service at the Ohio State University.</ServiceDescription>
+      <RequestedAttribute FriendlyName="displayName" Name="urn:mace:dir:attribute-def:displayName" NameFormat="urn:mace:shibboleth:1.0:attributeNamespace:uri"/>
+      <RequestedAttribute FriendlyName="displayName" Name="urn:oid:2.16.840.1.113730.3.1.241" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+      <RequestedAttribute FriendlyName="eduPersonPrincipalName" Name="urn:mace:dir:attribute-def:eduPersonPrincipalName" NameFormat="urn:mace:shibboleth:1.0:attributeNamespace:uri"/>
+      <RequestedAttribute FriendlyName="eduPersonPrincipalName" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+      <RequestedAttribute FriendlyName="mail" Name="urn:mace:dir:attribute-def:mail" NameFormat="urn:mace:shibboleth:1.0:attributeNamespace:uri"/>
+      <RequestedAttribute FriendlyName="mail" Name="urn:oid:0.9.2342.19200300.100.1.3" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+    </AttributeConsumingService>
+  </SPSSODescriptor>
+  <Organization>
+    <OrganizationName xml:lang="en">The Ohio State University</OrganizationName>
+    <OrganizationDisplayName xml:lang="en">Ohio State University</OrganizationDisplayName>
+    <OrganizationURL xml:lang="en"> </OrganizationURL>
+  </Organization>
+  <ContactPerson contactType="support">
+    <GivenName>IT Service Desk</GivenName>
+    <EmailAddress>8help at osu.edu</EmailAddress>
+  </ContactPerson>
+  <ContactPerson contactType="technical">
+    <GivenName>Web Authentication Support</GivenName>
+    <EmailAddress>webauth-admin at lists.service.ohio-state.edu</EmailAddress>
+  </ContactPerson>
+</EntityDescriptor>
+
+
+</EntitiesDescriptor>
diff --git a/opensaml-saml-impl/src/test/resources/org/opensaml/saml/saml2/metadata/valid-metadata.xml b/opensaml-saml-impl/src/test/resources/org/opensaml/saml/saml2/metadata/valid-metadata.xml
new file mode 100644
index 000000000..35ab4a5fd
--- /dev/null
+++ b/opensaml-saml-impl/src/test/resources/org/opensaml/saml/saml2/metadata/valid-metadata.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="urn:mace:incommon" xsi:schemaLocation="urn:oasis:names:tc:SAML:2.0:metadata sstc-saml-schema-metadata-2.0.xsd urn:mace:shibboleth:metadata:1.0 shibboleth-metadata-1.0.xsd http://www.w3.org/2000/09/xmldsig# xmldsig-core-schema.xsd">
+  <Extensions>
+    <shibmd:KeyAuthority xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" VerifyDepth="5">
+      <!-- InCommon CA -->
+      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+        <ds:X509Data>
+          <ds:X509Certificate>
+MIIFmjCCBIKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJVUzEc
+MBoGA1UEChMTSW5Db21tb24gRmVkZXJhdGlvbjEpMCcGA1UEAxMgSW5Db21tb24g
+Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwMzMwMjAzNDAwWhcNMTQwMzI5
+MjAzNDAwWjBWMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTSW5Db21tb24gRmVkZXJh
+dGlvbjEpMCcGA1UEAxMgSW5Db21tb24gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRGjKsUM2QAupLAaWx82/C
+WPalKjKFY8UPmz0T3gf7tJPztTy1Zq8pD0WFRLcQeSBKZGCu8upe8X966b6TZ5yu
+oUDA754If0DWismuHNoMgRR/l0UvZmPWDGRWd3NBTB8/soLA4EbqFf5Xq8MOJKhP
+tzcDR33gtaAb3oilZ+ZTpnhTFFrn/qXrAKcSDBpuW2JRpi3xaF/hTPI097oUShOz
+D1Zj21UYLA6iSFVN+1wlfwilf2KFNK/+zbkCge6wgipZyXxaOAam6ncqmkxy+hy/
+OiJMmdB+6xkO0xXSBUUcqxJrOcUQhA1vntgb3q5zOJISXhC4RAReA0HyBp/wd0iD
+AgMBAAGjggJxMIICbTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
+BgNVHQ4EFgQUky3IYRitY+ObZbOd3Y2TuufKY0UwfgYDVR0jBHcwdYAUky3IYRit
+Y+ObZbOd3Y2TuufKY0WhWqRYMFYxCzAJBgNVBAYTAlVTMRwwGgYDVQQKExNJbkNv
+bW1vbiBGZWRlcmF0aW9uMSkwJwYDVQQDEyBJbkNvbW1vbiBDZXJ0aWZpY2F0aW9u
+IEF1dGhvcml0eYIBADCBugYIKwYBBQUHAQEEga0wgaowgacGCCsGAQUFBzAChoGa
+aHR0cDovL2luY29tbW9uY2ExLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvYnJpZGdl
+L2NlcnRzL2NhLWNlcnRzLnA3YgoJCUNBIElzc3VlcnMgLSBVUkk6aHR0cDovL2lu
+Y29tbW9uY2EyLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvYnJpZGdlL2NlcnRzL2Nh
+LWNlcnRzLnA3YjCBjQYDVR0fBIGFMIGCMD+gPaA7hjlodHRwOi8vaW5jb21tb25j
+cmwxLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvY3JsL2VlY3Jscy5jcmwwP6A9oDuG
+OWh0dHA6Ly9pbmNvbW1vbmNybDIuaW5jb21tb25mZWRlcmF0aW9uLm9yZy9jcmwv
+ZWVjcmxzLmNybDBeBgNVHSAEVzBVMFMGCysGAQQBriMBBAEBMEQwQgYIKwYBBQUH
+AgEWNmh0dHA6Ly9pbmNvbW1vbmNhLmluY29tbW9uZmVkZXJhdGlvbi5vcmcvcHJh
+Y3RpY2VzLnBkZjANBgkqhkiG9w0BAQUFAAOCAQEAZfgKUPA+Ky+Ou/vclMlFTMlU
+GspfbNSdG/fmIq+E/Lv1d2c73Am1zGhOpxgdkM8SE+BPnXW2rl71/N8gaqwgBBxk
+pwn410siumxlDTwV3HoVFvCGWylNy9o8OE1LyTCqfo8PRwrMzhwcagDgD813BIyj
+uJg/JQz1LnHMocIW/JligloSIzF1O435/+ckfWXQsmBIhvV5TmA3ZrcycrI1cHGE
+ZqrCXL0FMZLSr+Vady/tFbVojqI8pSubSMxNkZectePTBjVj1Qeb4hmG8jRv/fwy
+1Iw6OFH8RKny8nQaO5mOe/fF/swEsMVU9TDpvLIgbhTwnP7Nhfotgaxf5wG8WA==
+          </ds:X509Certificate>
+        </ds:X509Data>
+      </ds:KeyInfo>
+    </shibmd:KeyAuthority>
+  </Extensions>
+<EntityDescriptor entityID="https://carmenwiki.osu.edu/shibboleth" xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
+  <Extensions xmlns:mdattr="urn:oasis:names:tc:SAML:metadata:attribute" xmlns:mdrpi="urn:oasis:names:tc:SAML:metadata:rpi">
+    <mdrpi:RegistrationInfo registrationAuthority="https://incommon.org"/>
+    <mdattr:EntityAttributes xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
+      <saml:Attribute Name="http://macedir.org/entity-category" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+        <saml:AttributeValue>http://id.incommon.org/category/research-and-scholarship</saml:AttributeValue>
+        <saml:AttributeValue>http://refeds.org/category/research-and-scholarship</saml:AttributeValue>
+        <saml:AttributeValue>http://id.incommon.org/category/registered-by-incommon</saml:AttributeValue>
+      </saml:Attribute>
+    </mdattr:EntityAttributes>
+  </Extensions>
+  <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:2.0:protocol">
+    <md:Extensions xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
+      <DiscoveryResponse xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://carmenwiki.osu.edu/Shibboleth.sso/Login" index="1"/>
+      <DiscoveryResponse xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://carmenwiki.it.ohio-state.edu/Shibboleth.sso/Login" index="2"/>
+      <DiscoveryResponse xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://carmenwiki.osu.edu/Shibboleth.sso/Clear" index="3"/>
+      <DiscoveryResponse xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="https://carmenwiki.it.ohio-state.edu/Shibboleth.sso/Clear" index="4"/>
+      <mdui:UIInfo xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui">
+        <mdui:DisplayName xml:lang="en">CarmenWiki</mdui:DisplayName>
+        <mdui:Description xml:lang="en">Enterprise Wiki Service at the Ohio State University.</mdui:Description>
+        <mdui:InformationURL xml:lang="en">https://ocio.osu.edu/services/view/carmenwiki-wiki-services</mdui:InformationURL>
+        <mdui:PrivacyStatementURL xml:lang="en">https://carmenwiki.osu.edu/x/jyLeAQ</mdui:PrivacyStatementURL>
+        <mdui:Logo height="85" width="141" xml:lang="en">https://carmenwiki.osu.edu/download/attachments/9666561/global.logo</mdui:Logo>
+      </mdui:UIInfo>
+    </md:Extensions>
+    <md:KeyDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
+      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+        <ds:X509Data>
+<!-- Serial No. 15149766524924023670, expires on Sat Jul  4 22:43:05 2020 GMT -->
+          <ds:X509Certificate>
+MIIDGzCCAgOgAwIBAgIJANI+yGM0M1N2MA0GCSqGSIb3DQEBBQUAMCcxJTAjBgNV
+BAMTHGx0Y2F3aWtpMDEuaXQub2hpby1zdGF0ZS5lZHUwHhcNMTAwNzA3MjI0MzA1
+WhcNMjAwNzA0MjI0MzA1WjAnMSUwIwYDVQQDExxsdGNhd2lraTAxLml0Lm9oaW8t
+c3RhdGUuZWR1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5fsEv25M
+r9wfa48qfjn8m40yB/lwimJ8dSnYw2erd/tfB+sPESw42Is5Lv2B3pI3mj9a0PT0
+Gf1VgUoQW0RCT6L4VOW50WsPFv/RKPfT/AIRl00dTCqb440PgotGbrK9ivZqlvkz
+lSGUKuFcg2gLj+CJlbMcwEneSwn0FE1xKEGpMDUk91lZH1XxmnIDDOQn1G5qul4q
+AbXITMpLi2MlsHAEXxnLrthFFas6zDrviTwHcqGXq9zJJkPHDcbu1qg6AUT7bRJr
+qszxxktSV6mFclkgLPpcVkigMR8RNVMQkWaaWSnfBkFy2iAe3xw3DNp7obtzgItY
+i9N8U6K5qorSkQIDAQABo0owSDAnBgNVHREEIDAeghxsdGNhd2lraTAxLml0Lm9o
+aW8tc3RhdGUuZWR1MB0GA1UdDgQWBBR32XnCliG78DdyTtZhyIQSHChtyjANBgkq
+hkiG9w0BAQUFAAOCAQEAVEweCxPElHGmam4Iv2QeJsGE7m4de7axp3epAJb7uVbN
+Z2P1S/s4GZQhmGsUoGoxwqca3wyQ+C1ZkpQJdyFl5s1tFc26D+Z0KTDo174GzO9i
+I9SeQ4YSp3FNhZqxn4xH3DULzzHwoVSwFr5irLPAVtrqK8H/rzBREhqOse2VSJ/1
+PkI+p7lUiElIzMiObLGjumF2fDOPkXOSMNyC4c5oCCJtcrip/BaLo6bqdqn3DKP8
+onMw/lHZQolyVsupuhGsSX13WVJ0uyGvuA7hiHnGEkpDmskUd3TsriyQAt47RZzY
+tTupO/NdWvz8SvXU1qIOk9CTQ0D2b2OOftfUW+FuAQ==
+          </ds:X509Certificate>
+        </ds:X509Data>
+      </ds:KeyInfo>
+    </md:KeyDescriptor>
+    <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="https://carmenwiki.osu.edu/Shibboleth.sso/SAML/POST" index="1"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" Location="https://carmenwiki.osu.edu/Shibboleth.sso/SAML/Artifact" index="2"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="https://carmenwiki.it.ohio-state.edu/Shibboleth.sso/SAML/POST" index="3"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" Location="https://carmenwiki.it.ohio-state.edu/Shibboleth.sso/SAML/Artifact" index="4"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://carmenwiki.osu.edu/Shibboleth.sso/SAML2/POST" index="5"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://carmenwiki.osu.edu/Shibboleth.sso/SAML2/Artifact" index="6"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://carmenwiki.it.ohio-state.edu/Shibboleth.sso/SAML2/POST" index="7"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://carmenwiki.it.ohio-state.edu/Shibboleth.sso/SAML2/Artifact" index="8"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://carmenwiki.osu.edu/Shibboleth.sso/SAML2/ECP" index="9"/>
+    <md:AssertionConsumerService xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://carmenwiki.it.ohio-state.edu/Shibboleth.sso/SAML2/ECP" index="10"/>
+    <AttributeConsumingService xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" index="1">
+      <ServiceName xml:lang="en">CarmenWiki</ServiceName>
+      <ServiceDescription xml:lang="en">Enterprise Wiki Service at the Ohio State University.</ServiceDescription>
+      <RequestedAttribute FriendlyName="displayName" Name="urn:mace:dir:attribute-def:displayName" NameFormat="urn:mace:shibboleth:1.0:attributeNamespace:uri"/>
+      <RequestedAttribute FriendlyName="displayName" Name="urn:oid:2.16.840.1.113730.3.1.241" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+      <RequestedAttribute FriendlyName="eduPersonPrincipalName" Name="urn:mace:dir:attribute-def:eduPersonPrincipalName" NameFormat="urn:mace:shibboleth:1.0:attributeNamespace:uri"/>
+      <RequestedAttribute FriendlyName="eduPersonPrincipalName" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+      <RequestedAttribute FriendlyName="mail" Name="urn:mace:dir:attribute-def:mail" NameFormat="urn:mace:shibboleth:1.0:attributeNamespace:uri"/>
+      <RequestedAttribute FriendlyName="mail" Name="urn:oid:0.9.2342.19200300.100.1.3" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"/>
+    </AttributeConsumingService>
+  </SPSSODescriptor>
+  <Organization>
+    <OrganizationName xml:lang="en">The Ohio State University</OrganizationName>
+    <OrganizationDisplayName xml:lang="en">Ohio State University</OrganizationDisplayName>
+    <OrganizationURL xml:lang="en">http://www.osu.edu/</OrganizationURL>
+  </Organization>
+  <ContactPerson contactType="support">
+    <GivenName>IT Service Desk</GivenName>
+    <EmailAddress>8help at osu.edu</EmailAddress>
+  </ContactPerson>
+  <ContactPerson contactType="technical">
+    <GivenName>Web Authentication Support</GivenName>
+    <EmailAddress>webauth-admin at lists.service.ohio-state.edu</EmailAddress>
+  </ContactPerson>
+</EntityDescriptor>
+
+
+</EntitiesDescriptor>

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


More information about the commits mailing list