Hi, this is a rather specific problem, I suppose: we're using java-saml in a plugin for a third-party service. The plugin is loaded by an OSGi framework in this service. We don't have any control over the OSGi bundle manifests.
In this context, XML validation during Auth.processResponse fails to load the schema resource files with MalformedURLException: unknown protocol: bundle:
jvm 1 | 2022-04-19 10:12:27,990 WARN [qtp1903462050-26] p.c.a.g.s.p.c.a.g.s.s.JavaSamlLogPropagator:97 [plugin-ch.adnovum.gocd.saml2.plugin] - org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'bundle://00a4a7ff-512c-49a7-b4f0-ebbd54ac8a10_7.0:5/schemas/saml-schema-protocol-2.0.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaError(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getSchemaDocument1(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getSchemaDocument(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(Unknown Source)
jvm 1 | at java.xml/javax.xml.validation.SchemaFactory.newSchema(Unknown Source)
jvm 1 | at java.xml/javax.xml.validation.SchemaFactory.newSchema(Unknown Source)
jvm 1 | at com.onelogin.saml2.util.SchemaFactory.loadFromUrl(SchemaFactory.java:106)
jvm 1 | at com.onelogin.saml2.util.Util.validateXML(Util.java:305)
jvm 1 | at com.onelogin.saml2.authn.SamlResponse.isValid(SamlResponse.java:220)
[...]
jvm 1 | Caused by: java.net.MalformedURLException: unknown protocol: bundle
jvm 1 | at java.base/java.net.URL.<init>(Unknown Source)
jvm 1 | at java.base/java.net.URL.<init>(Unknown Source)
jvm 1 | at java.base/java.net.URL.<init>(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaParsingConfig.parse(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaParsingConfig.parse(Unknown Source)
jvm 1 | at java.xml/com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaDOMParser.parse(Unknown Source)
jvm 1 | ... 148 common frames omitted
In general, resource loading works fine in the plugin. I'm not sure why it's not working specifically for the javax.xml.validation.SchemaFactory:newSchema call. I also must admit I don't know enough about OSGi to pinpoint what could be happening here.
At the moment, I'm working around this by using a custom SamlMessageFactory that creates SamlResponses with custom xml validation, using an adapted SchemaFactory which loads the schemas via getResourceAsStream instead of URLs:
public abstract class SchemaFactory {
// Resource path string instead of URL:
public static final String SAML_SCHEMA_METADATA_2_0 = "/schemas/saml-schema-metadata-2.0.xsd";
public static final String SAML_SCHEMA_PROTOCOL_2_0 = "/schemas/saml-schema-protocol-2.0.xsd";
// Pass resource string instead of URL:
public static Schema loadFromUrl(String schemaResourcePath) throws SAXException {
[...]
// Loads this via getResourceAsStream instead of directly from URL:
InputStream inputStream = SchemaFactory.class.getResourceAsStream(schemaResourcePath);
return factory.newSchema(new StreamSource(inputStream));
}
}
I figured I'd report it, in case you've seen this before and know a better solution, or perhaps you're willing to accept that workaround, though it unfortunately breaks the API of SchemaFactory.
Hi, this is a rather specific problem, I suppose: we're using java-saml in a plugin for a third-party service. The plugin is loaded by an OSGi framework in this service. We don't have any control over the OSGi bundle manifests.
In this context, XML validation during
Auth.processResponse
fails to load the schema resource files withMalformedURLException: unknown protocol: bundle
:In general, resource loading works fine in the plugin. I'm not sure why it's not working specifically for the
javax.xml.validation.SchemaFactory:newSchema
call. I also must admit I don't know enough about OSGi to pinpoint what could be happening here.At the moment, I'm working around this by using a custom
SamlMessageFactory
that createsSamlResponse
s with custom xml validation, using an adaptedSchemaFactory
which loads the schemas viagetResourceAsStream
instead of URLs:I figured I'd report it, in case you've seen this before and know a better solution, or perhaps you're willing to accept that workaround, though it unfortunately breaks the API of SchemaFactory.