Skip to content

Commit 0a90a87

Browse files
authored
Merge pull request #332 from mauromol/enforce-local-schema-resolution
Ensure local resolution of schemas (and DTDs)
2 parents 3125450 + 3edc899 commit 0a90a87

File tree

4 files changed

+696
-3
lines changed

4 files changed

+696
-3
lines changed

core/src/main/java/com/onelogin/saml2/util/SchemaFactory.java

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
package com.onelogin.saml2.util;
22

3+
import java.io.InputStream;
34
import java.net.URL;
5+
import java.util.Locale;
46

57
import javax.xml.XMLConstants;
68
import 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;
816
import org.xml.sax.SAXException;
917

1018
/**
@@ -14,6 +22,11 @@
1422
*/
1523
public 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

Comments
 (0)