Support both SAML 1.0 and 1.1 schemas
authorgilbert <gilbert@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Tue, 29 Mar 2005 22:04:21 +0000 (22:04 +0000)
committergilbert <gilbert@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Tue, 29 Mar 2005 22:04:21 +0000 (22:04 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@1350 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

src/edu/internet2/middleware/shibboleth/xml/Parser.java
src/edu/internet2/middleware/shibboleth/xml/SchemasDirectoryImpl.java
src/schemas/saml-1.0/cs-sstc-schema-assertion-01.xsd [new file with mode: 0644]
src/schemas/saml-1.0/cs-sstc-schema-protocol-01.xsd [new file with mode: 0644]

index 82198d2..af15959 100644 (file)
@@ -82,8 +82,9 @@ public class Parser {
     
     // If there were a real Framework here (like Spring) then
     // the schemaBuilder would be inserted 
-    private static Schemas schemaBuilder = new SchemasDirectoryImpl();
+    private static SchemasDirectoryImpl schemaBuilder = new SchemasDirectoryImpl();
     private static Schema schema = schemaBuilder.compileSchema(namespaces);
+       private static Schema schemaOldSAML= schemaBuilder.compileSchema(namespaces,"/schemas/saml-1.0/");
     
     /**
      * Load a DOM from a wrapped byte stream.
@@ -183,7 +184,8 @@ public class Parser {
      * SAML 1.1 plus Shibboleth (and some SAML 2.0).
      */
     static {
-        org.opensaml.XML.parserPool.setDefaultSchema(schema);
+        //org.opensaml.XML.parserPool.setDefaultSchema(schema);
+               org.opensaml.XML.parserPool.setDefaultSchemas(schemaOldSAML,schema);
     }
     
 }
\ No newline at end of file
index 5a58314..5cdc45b 100644 (file)
@@ -36,6 +36,9 @@ public class SchemasDirectoryImpl implements Schemas {
     // The default is the /schemas/ resource directory in the WAR file.
     private String resourcedir = "/schemas/";
 
+    private Map bucket = new HashMap();
+       
+       
     public String getResourcedir() {
         return resourcedir;
     }
@@ -69,12 +72,7 @@ public class SchemasDirectoryImpl implements Schemas {
      * @param resourcedir Resource directory with schema files ("/schemas/")
      * @return Schema object combining all namespaces.
      */
-    public Schema compileSchema(String[] namespaces) {
-        
-        Schema schema = null;
-        
-        Map bucket = new HashMap();
-        
+    public Schema compileSchema(String[] namespaces, String resourcedir) {
         // Find a directory of schemas
         // It is a resource in WEB-INF/classes or the same jar file
         // from which this class was loaded.
@@ -86,10 +84,42 @@ public class SchemasDirectoryImpl implements Schemas {
             return null;
         }
         
-        // for each .xsd file in the directory
+        loadBucketFromDirectory(bucket, dir);
+        
+        return generateSchema(namespaces, bucket);
+        
+    }
+       
+       public Schema compileSchema(String[] namespaces) {
+               return compileSchema(namespaces,this.resourcedir);
+       }
+
+       private Schema generateSchema(String[] namespaces, Map bucket) {
+               Schema schema = null;
+               ArrayList sources = new ArrayList();
+               for (int i=0;i<namespaces.length;i++) {
+            Document doc = (Document) bucket.get(namespaces[i]);
+            if (doc==null) {
+                log.error("Schema missing for namespace (" +namespaces[i] + ").");
+            } else {
+            sources.add(new DOMSource(doc));
+            }
+        }
+               // Now compile all the XSD files into a single composite Schema object
+        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+               try {
+            schema = factory.newSchema((Source[]) sources.toArray(new Source[0]));
+        } catch (SAXException e) {
+            log.error("Schemas failed to compile, dependencies may be corrupt: " +e);
+        }
+               return schema;
+       }
+
+       private void loadBucketFromDirectory(Map bucket, File dir) {
+               // for each .xsd file in the directory
         String[] filenames = dir.list();
-        int nextsource=0;
-        for (int i=0;i<filenames.length;i++) {
+               int nextsource=0;
+               for (int i=0;i<filenames.length;i++) {
             String filename = filenames[i];
             if (!filename.endsWith(".xsd"))
                 continue;
@@ -121,36 +151,12 @@ public class SchemasDirectoryImpl implements Schemas {
             
             // Put the DOM in the Bucket keyed by namespace
             if (bucket.containsKey(targetNamespace)) {
-                log.error("Schema for already defined namespace: "+targetNamespace+" "+filename);
-                continue;
-            }
-            bucket.put(targetNamespace,xsddom);
-        }
-        
-        // Ok, so now we have a bucket of DOM objects keyed by the 
-        // namespaces that they internally declare they define
-        
-        // Now we have a list of Namespaces in the order we need 
-        // to process them (imported dependencies first)
-        ArrayList sources = new ArrayList();
-        for (int i=0;i<namespaces.length;i++) {
-            Document doc = (Document) bucket.get(namespaces[i]);
-            if (doc==null) {
-                log.error("Schema missing for namespace (" +namespaces[i] + ").");
+                log.debug("Replacing XSD for namespace: "+targetNamespace+" "+filename);
             } else {
-            sources.add(new DOMSource(doc));
+                log.debug("Defining XSD for namespace:  "+targetNamespace+" "+filename);
             }
+            bucket.put(targetNamespace,xsddom);
         }
-        
-        // Now compile all the XSD files into a single composite Schema object
-        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-        try {
-            schema = factory.newSchema((Source[]) sources.toArray(new Source[0]));
-        } catch (SAXException e) {
-            log.error("Schemas failed to compile, dependencies may be corrupt: " +e);
-        }
-        return schema;
-        
-    }
+       }
 
 }
diff --git a/src/schemas/saml-1.0/cs-sstc-schema-assertion-01.xsd b/src/schemas/saml-1.0/cs-sstc-schema-assertion-01.xsd
new file mode 100644 (file)
index 0000000..d41f3e8
--- /dev/null
@@ -0,0 +1,194 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- edited with XML Spy v3.5 NT (http://www.xmlspy.com) by Phill Hallam-Baker (VeriSign Inc.) -->
+<schema targetNamespace="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified">
+        <import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd"/>
+        <annotation>
+                <documentation>
+                Document identifier: cs-sstc-schema-assertion-01
+                Location: http://www.oasis-open.org/committees/security/docs/
+                </documentation>
+        </annotation>
+        <simpleType name="IDType">
+                <restriction base="string"/>
+        </simpleType>
+        <simpleType name="IDReferenceType">
+                <restriction base="string"/>
+        </simpleType>
+        <simpleType name="DecisionType">
+                <restriction base="string">
+                        <enumeration value="Permit"/>
+                        <enumeration value="Deny"/>
+                        <enumeration value="Indeterminate"/>
+                </restriction>
+        </simpleType>
+        <element name="AssertionIDReference" type="saml:IDReferenceType"/>
+        <element name="Assertion" type="saml:AssertionType"/>
+        <complexType name="AssertionType">
+                <sequence>
+                        <element ref="saml:Conditions" minOccurs="0"/>
+                        <element ref="saml:Advice" minOccurs="0"/>
+                        <choice maxOccurs="unbounded">
+                                <element ref="saml:Statement"/>
+                                <element ref="saml:SubjectStatement"/>
+                                <element ref="saml:AuthenticationStatement"/>
+                                <element ref="saml:AuthorizationDecisionStatement"/>
+                                <element ref="saml:AttributeStatement"/>
+                        </choice>
+                        <element ref="ds:Signature" minOccurs="0"/>
+                </sequence>
+                <attribute name="MajorVersion" type="integer" use="required"/>
+                <attribute name="MinorVersion" type="integer" use="required"/>
+                <attribute name="AssertionID" type="saml:IDType" use="required"/>
+                <attribute name="Issuer" type="string" use="required"/>
+                <attribute name="IssueInstant" type="dateTime" use="required"/>
+        </complexType>
+        <element name="Conditions" type="saml:ConditionsType"/>
+        <complexType name="ConditionsType">
+                <choice minOccurs="0" maxOccurs="unbounded">
+                        <element ref="saml:AudienceRestrictionCondition"/>
+                        <element ref="saml:Condition"/>
+                </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="AudienceRestrictionCondition" type="saml:AudienceRestrictionConditionType"/>
+        <complexType name="AudienceRestrictionConditionType">
+                <complexContent>
+                        <extension base="saml:ConditionAbstractType">
+                                <sequence>
+                                        <element ref="saml:Audience" maxOccurs="unbounded"/>
+                                </sequence>
+                        </extension>
+                </complexContent>
+        </complexType>
+        <element name="Audience" type="anyURI"/>
+        <element name="Advice" type="saml:AdviceType"/>
+        <complexType name="AdviceType">
+                <choice minOccurs="0" maxOccurs="unbounded">
+                        <element ref="saml:AssertionIDReference"/>
+                        <element ref="saml:Assertion"/>
+                        <any namespace="##other" processContents="lax"/>
+                </choice>
+        </complexType>
+        <element name="Statement" type="saml:StatementAbstractType"/>
+        <complexType name="StatementAbstractType" abstract="true"/>
+        <element name="SubjectStatement" type="saml:SubjectStatementAbstractType"/>
+        <complexType name="SubjectStatementAbstractType" abstract="true">
+                <complexContent>
+                        <extension base="saml:StatementAbstractType">
+                                <sequence>
+                                        <element ref="saml:Subject"/>
+                                </sequence>
+                        </extension>
+                </complexContent>
+        </complexType>
+        <element name="Subject" type="saml:SubjectType"/>
+        <complexType name="SubjectType">
+                <choice>
+                        <sequence>
+                                <element ref="saml:NameIdentifier"/>
+                                <element ref="saml:SubjectConfirmation" minOccurs="0"/>
+                        </sequence>
+                        <element ref="saml:SubjectConfirmation"/>
+                </choice>
+        </complexType>
+        <element name="NameIdentifier" type="saml:NameIdentifierType"/>
+        <complexType name="NameIdentifierType">
+                <simpleContent>
+                        <extension base="string">
+                                <attribute name="NameQualifier" type="string" use="optional"/>
+                                <attribute name="Format" type="anyURI" use="optional"/>
+                        </extension>
+                </simpleContent>
+        </complexType>
+        <element name="SubjectConfirmation" type="saml:SubjectConfirmationType"/>
+        <complexType name="SubjectConfirmationType">
+                <sequence>
+                        <element ref="saml:ConfirmationMethod" maxOccurs="unbounded"/>
+                        <element ref="saml:SubjectConfirmationData" minOccurs="0"/>
+                        <element ref="ds:KeyInfo" minOccurs="0"/>
+                </sequence>
+        </complexType>
+        <element name="SubjectConfirmationData" type="anyType"/>
+        <element name="ConfirmationMethod" type="anyURI"/>
+        <element name="AuthenticationStatement" type="saml:AuthenticationStatementType"/>
+        <complexType name="AuthenticationStatementType">
+                <complexContent>
+                        <extension base="saml:SubjectStatementAbstractType">
+                                <sequence>
+                                        <element ref="saml:SubjectLocality" minOccurs="0"/>
+                                        <element ref="saml:AuthorityBinding" minOccurs="0" maxOccurs="unbounded"/>
+                                </sequence>
+                                <attribute name="AuthenticationMethod" type="anyURI" use="required"/>
+                                <attribute name="AuthenticationInstant" type="dateTime" use="required"/>
+                        </extension>
+                </complexContent>
+        </complexType>
+        <element name="SubjectLocality" type="saml:SubjectLocalityType"/>
+        <complexType name="SubjectLocalityType">
+                <attribute name="IPAddress" type="string" use="optional"/>
+                <attribute name="DNSAddress" type="string" use="optional"/>
+        </complexType>
+        <element name="AuthorityBinding" type="saml:AuthorityBindingType"/>
+        <complexType name="AuthorityBindingType">
+                <attribute name="AuthorityKind" type="QName" use="required"/>
+                <attribute name="Location" type="anyURI" use="required"/>
+                <attribute name="Binding" type="anyURI" use="required"/>
+        </complexType>
+        <element name="AuthorizationDecisionStatement" type="saml:AuthorizationDecisionStatementType"/>
+        <complexType name="AuthorizationDecisionStatementType">
+                <complexContent>
+                        <extension base="saml:SubjectStatementAbstractType">
+                                <sequence>
+                                        <element ref="saml:Action" maxOccurs="unbounded"/>
+                                        <element ref="saml:Evidence" minOccurs="0"/>
+                                </sequence>
+                                <attribute name="Resource" type="anyURI" use="required"/>
+                                <attribute name="Decision" type="saml:DecisionType" use="required"/>
+                        </extension>
+                </complexContent>
+        </complexType>
+        <element name="Action" type="saml:ActionType"/>
+        <complexType name="ActionType">
+                <simpleContent>
+                        <extension base="string">
+                                <attribute name="Namespace" type="anyURI"/>
+                        </extension>
+                </simpleContent>
+        </complexType>
+        <element name="Evidence" type="saml:EvidenceType"/>
+        <complexType name="EvidenceType">
+                <choice maxOccurs="unbounded">
+                        <element ref="saml:AssertionIDReference"/>
+                        <element ref="saml:Assertion"/>
+                </choice>
+        </complexType>
+        <element name="AttributeStatement" type="saml:AttributeStatementType"/>
+        <complexType name="AttributeStatementType">
+                <complexContent>
+                        <extension base="saml:SubjectStatementAbstractType">
+                                <sequence>
+                                        <element ref="saml:Attribute" maxOccurs="unbounded"/>
+                                </sequence>
+                        </extension>
+                </complexContent>
+        </complexType>
+        <element name="AttributeDesignator" type="saml:AttributeDesignatorType"/>
+        <complexType name="AttributeDesignatorType">
+                <attribute name="AttributeName" type="string" use="required"/>
+                <attribute name="AttributeNamespace" type="anyURI" use="required"/>
+        </complexType>
+        <element name="Attribute" type="saml:AttributeType"/>
+        <complexType name="AttributeType">
+                <complexContent>
+                        <extension base="saml:AttributeDesignatorType">
+                                <sequence>
+                                        <element ref="saml:AttributeValue" maxOccurs="unbounded"/>
+                                </sequence>
+                        </extension>
+                </complexContent>
+        </complexType>
+        <element name="AttributeValue" type="anyType"/>
+</schema>
diff --git a/src/schemas/saml-1.0/cs-sstc-schema-protocol-01.xsd b/src/schemas/saml-1.0/cs-sstc-schema-protocol-01.xsd
new file mode 100644 (file)
index 0000000..d939fa7
--- /dev/null
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- edited with XML Spy v4.2 U (http://www.xmlspy.com) by Phillip Hallam-Baker (Phillip Hallam-Baker) -->
+<schema targetNamespace="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified">
+        <import namespace="urn:oasis:names:tc:SAML:1.0:assertion" schemaLocation="cs-sstc-schema-assertion-01.xsd"/>
+        <import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd"/>
+        <annotation>
+                <documentation>
+                Document identifier: cs-sstc-schema-protocol-01
+                Location: http://www.oasis-open.org/committees/security/docs/
+                </documentation>
+        </annotation>
+        <complexType name="RequestAbstractType" abstract="true">
+                <sequence>
+                        <element ref="samlp:RespondWith" minOccurs="0" maxOccurs="unbounded"/>
+                        <element ref="ds:Signature" minOccurs="0"/>
+                </sequence>
+                <attribute name="RequestID" type="saml:IDType" use="required"/>
+                <attribute name="MajorVersion" type="integer" use="required"/>
+                <attribute name="MinorVersion" type="integer" use="required"/>
+                <attribute name="IssueInstant" type="dateTime" use="required"/>
+        </complexType>
+        <element name="RespondWith" type="QName"/>
+        <element name="Request" type="samlp:RequestType"/>
+        <complexType name="RequestType">
+                <complexContent>
+                        <extension base="samlp:RequestAbstractType">
+                                <choice>
+                                        <element ref="samlp:Query"/>
+                                        <element ref="samlp:SubjectQuery"/>
+                                        <element ref="samlp:AuthenticationQuery"/>
+                                        <element ref="samlp:AttributeQuery"/>
+                                        <element ref="samlp:AuthorizationDecisionQuery"/>
+                                        <element ref="saml:AssertionIDReference" maxOccurs="unbounded"/>
+                                        <element ref="samlp:AssertionArtifact" maxOccurs="unbounded"/>
+                                </choice>
+                        </extension>
+                </complexContent>
+        </complexType>
+        <element name="AssertionArtifact" type="string"/>
+        <element name="Query" type="samlp:QueryAbstractType"/>
+        <complexType name="QueryAbstractType" abstract="true"/>
+        <element name="SubjectQuery" type="samlp:SubjectQueryAbstractType"/>
+        <complexType name="SubjectQueryAbstractType" abstract="true">
+                <complexContent>
+                        <extension base="samlp:QueryAbstractType">
+                                <sequence>
+                                        <element ref="saml:Subject"/>
+                                </sequence>
+                        </extension>
+                </complexContent>
+        </complexType>
+        <element name="AuthenticationQuery" type="samlp:AuthenticationQueryType"/>
+        <complexType name="AuthenticationQueryType">
+                <complexContent>
+                        <extension base="samlp:SubjectQueryAbstractType">
+                                <attribute name="AuthenticationMethod" type="anyURI"/>
+                        </extension>
+                </complexContent>
+        </complexType>
+        <element name="AttributeQuery" type="samlp:AttributeQueryType"/>
+        <complexType name="AttributeQueryType">
+                <complexContent>
+                        <extension base="samlp:SubjectQueryAbstractType">
+                                <sequence>
+                                        <element ref="saml:AttributeDesignator" minOccurs="0" maxOccurs="unbounded"/>
+                                </sequence>
+                                <attribute name="Resource" type="anyURI" use="optional"/>
+                        </extension>
+                </complexContent>
+        </complexType>
+        <element name="AuthorizationDecisionQuery" type="samlp:AuthorizationDecisionQueryType"/>
+        <complexType name="AuthorizationDecisionQueryType">
+                <complexContent>
+                        <extension base="samlp:SubjectQueryAbstractType">
+                                <sequence>
+                                        <element ref="saml:Action" maxOccurs="unbounded"/>
+                                        <element ref="saml:Evidence" minOccurs="0" maxOccurs="1"/>
+                                </sequence>
+                                <attribute name="Resource" type="anyURI" use="required"/>
+                        </extension>
+                </complexContent>
+        </complexType>
+        <complexType name="ResponseAbstractType" abstract="true">
+                <sequence>
+                        <element ref="ds:Signature" minOccurs="0"/>
+                </sequence>
+                <attribute name="ResponseID" type="saml:IDType" use="required"/>
+                <attribute name="InResponseTo" type="saml:IDReferenceType" use="optional"/>
+                <attribute name="MajorVersion" type="integer" use="required"/>
+                <attribute name="MinorVersion" type="integer" use="required"/>
+                <attribute name="IssueInstant" type="dateTime" use="required"/>
+                <attribute name="Recipient" type="anyURI" use="optional"/>
+        </complexType>
+        <element name="Response" type="samlp:ResponseType"/>
+        <complexType name="ResponseType">
+                <complexContent>
+                        <extension base="samlp:ResponseAbstractType">
+                                <sequence>
+                                        <element ref="samlp:Status"/>
+                                        <element ref="saml:Assertion" minOccurs="0" maxOccurs="unbounded"/>
+                                </sequence>
+                        </extension>
+                </complexContent>
+        </complexType>
+        <element name="Status" type="samlp:StatusType"/>
+        <complexType name="StatusType">
+                <sequence>
+                        <element ref="samlp:StatusCode"/>
+                        <element ref="samlp:StatusMessage" minOccurs="0" maxOccurs="1"/>
+                        <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="QName" use="required"/>
+        </complexType>
+        <element name="StatusMessage" type="string"/>
+        <element name="StatusDetail" type="samlp:StatusDetailType"/>
+        <complexType name="StatusDetailType">
+                <sequence>
+                        <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+                </sequence>
+        </complexType>
+</schema>