11package com .onelogin .saml2 .util ;
22
3+ import java .io .InputStream ;
34import java .net .URL ;
5+ import java .util .Locale ;
46
57import javax .xml .XMLConstants ;
68import javax .xml .validation .Schema ;
79
10+ import org .slf4j .Logger ;
11+ import org .slf4j .LoggerFactory ;
12+ import org .w3c .dom .bootstrap .DOMImplementationRegistry ;
13+ import org .w3c .dom .ls .DOMImplementationLS ;
14+ import org .w3c .dom .ls .LSInput ;
15+ import org .w3c .dom .ls .LSResourceResolver ;
816import org .xml .sax .SAXException ;
917
1018/**
1422 */
1523public abstract class SchemaFactory {
1624
25+ /**
26+ * Private property to construct a logger for this class.
27+ */
28+ private static final Logger LOGGER = LoggerFactory .getLogger (SchemaFactory .class );
29+
1730 private SchemaFactory () {
1831 //not called
1932 }
@@ -24,7 +37,72 @@ private SchemaFactory() {
2437 .getResource ("/schemas/saml-schema-protocol-2.0.xsd" );
2538
2639 public static Schema loadFromUrl (URL schemaUrl ) throws SAXException {
27- return javax .xml .validation .SchemaFactory
28- .newInstance (XMLConstants .W3C_XML_SCHEMA_NS_URI ).newSchema (schemaUrl );
40+ javax .xml .validation .SchemaFactory factory = javax .xml .validation .SchemaFactory
41+ .newInstance (XMLConstants .W3C_XML_SCHEMA_NS_URI );
42+ factory .setResourceResolver (new LSResourceResolver () {
43+
44+ private DOMImplementationLS ls ;
45+
46+ @ Override
47+ public LSInput resolveResource (final String type , final String namespaceURI ,
48+ final String publicId , final String systemId , final String baseURI ) {
49+ try {
50+ if (namespaceURI != null )
51+ switch (namespaceURI ) {
52+ case "urn:oasis:names:tc:SAML:2.0:assertion" :
53+ return getLocalResource ("saml-schema-assertion-2.0.xsd" );
54+ case "urn:oasis:names:tc:SAML:2.0:ac" :
55+ return getLocalResource ("saml-schema-authn-context-2.0.xsd" );
56+ case "urn:oasis:names:tc:SAML:2.0:metadata" :
57+ return getLocalResource ("saml-schema-metadata-2.0.xsd" );
58+ case "urn:oasis:names:tc:SAML:2.0:protocol" :
59+ return getLocalResource ("saml-schema-protocol-2.0.xsd" );
60+ case "urn:oasis:names:tc:SAML:metadata:attribute" :
61+ return getLocalResource ("sstc-metadata-attr.xsd" );
62+ case "urn:oasis:names:tc:SAML:attribute:ext" :
63+ return getLocalResource ("sstc-saml-attribute-ext.xsd" );
64+ case "urn:oasis:names:tc:SAML:metadata:algsupport" :
65+ return getLocalResource ("sstc-saml-metadata-algsupport-v1.0.xsd" );
66+ case "urn:oasis:names:tc:SAML:metadata:ui" :
67+ return getLocalResource ("sstc-saml-metadata-ui-v1.0.xsd" );
68+ case "http://www.w3.org/2001/04/xmlenc#" :
69+ return getLocalResource ("xenc-schema.xsd" );
70+ case "http://www.w3.org/XML/1998/namespace" :
71+ return getLocalResource ("xml.xsd" );
72+ case "http://www.w3.org/2000/09/xmldsig#" :
73+ return getLocalResource ("xmldsig-core-schema.xsd" );
74+ }
75+ if ("saml-schema-authn-context-types-2.0.xsd" .equals (systemId ))
76+ return getLocalResource ("saml-schema-authn-context-types-2.0.xsd" );
77+ if (publicId != null )
78+ switch (publicId .toUpperCase (Locale .ROOT )) {
79+ case "-//W3C//DTD XMLSCHEMA 200102//EN" :
80+ return getLocalResource ("XMLSchema.dtd" );
81+ case "DATATYPES" :
82+ return getLocalResource ("datatypes.dtd" );
83+ }
84+ } catch (final Throwable e ) {
85+ // fallback to standard behaviour in case of errors
86+ LOGGER .warn ("could not resolve schema or DTD locally, proceeding the standard way" ,
87+ e );
88+ return null ;
89+ }
90+ return null ;
91+ }
92+
93+ public LSInput getLocalResource (String name ) throws Throwable {
94+ if (ls == null ) {
95+ DOMImplementationRegistry registry = DOMImplementationRegistry .newInstance ();
96+ ls = (DOMImplementationLS ) registry .getDOMImplementation ("LS 3.0" );
97+ }
98+ final InputStream inputStream = getClass ().getResourceAsStream ("/schemas/" + name );
99+ if (inputStream == null )
100+ return null ;
101+ final LSInput lsInput = ls .createLSInput ();
102+ lsInput .setByteStream (inputStream );
103+ return lsInput ;
104+ }
105+ });
106+ return factory .newSchema (schemaUrl );
29107 }
30108}
0 commit comments