We did an upgrade of SpringBoot framework to version 2.6.10, however our app was not starting without spring-boot-starter-validation dependency, which we added:
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation', version: '2.6.10'
After this change, it's not possible to access our XSD files during their validation via http address. Our XSD validation implementation:
import org.springframework.core.io.UrlResource;
import org.springframework.xml.validation.XmlValidator;
import org.springframework.xml.validation.XmlValidatorFactory;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import javax.xml.XMLConstants;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
public class XsdValidator {
public static final String ACCESS_EXTERNAL_SCHEMA = "javax.xml.accessExternalSchema";
public static final String ACCESS_EXTERNAL_SCHEMA_VALUE = "all";
/**
* Constructor.
*/
private XsdValidator() {
// not used
}
/**
* Validates the given XML against XSD schema referenced as URL resource.
*
* @param xml XML
* @param xsdUrl XSD URL
* @return list of validation exceptions, if there are any
* @throws IOException in case of I/O error - reading URL resource
*/
public static SAXParseException[] validateXml(String xml, String xsdUrl) throws IOException {
System.setProperty(ACCESS_EXTERNAL_SCHEMA, ACCESS_EXTERNAL_SCHEMA_VALUE);
final XmlValidator validator = XmlValidatorFactory.createValidator(new UrlResource(xsdUrl), XmlValidatorFactory.SCHEMA_W3C_XML);
return validator.validate(new StreamSource(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))));
}
The validation fails with following error:
Could not create Schema: schema_reference: Failed to read schema document 'my-xsd.xsd', because 'http' access is not allowed due to restriction set by the accessExternalSchema property. ; nested exception is org.xml.sax.SAXParseException; systemId: http://my-webserver.my-namespace.svc.cluster.local:80/xsd/my-system/my-xsd.xsd; lineNumber: 9; columnNumber: 68; schema_reference: Failed to read schema document 'my-xsd.xsd', because 'http' access is not allowed due to restriction set by the accessExternalSchema property. StackTrace:
at > org.springframework.xml.validation.Jaxp15ValidatorFactory.createValidat> or(Jaxp15ValidatorFactory.java:53) ~[spring-xml-3.1.3.jar:?] at > org.springframework.xml.validation.XmlValidatorFactory.createValidator(> XmlValidatorFactory.java:93) ~[spring-xml-3.1.3.jar:?] at > org.springframework.xml.validation.XmlValidatorFactory.createValidator(> XmlValidatorFactory.java:65) ~[spring-xml-3.1.3.jar:?] ...
Caused by: org.xml.sax.SAXParseException: schema_reference: Failed to > read schema document 'my-xsd.xsd', because 'http' access is not > allowed due to restriction set by the accessExternalSchema property. at > com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXPa> rseException(ErrorHandlerWrapper.java:204) ~[?:1.8.0_261] at > com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(> ErrorHandlerWrapper.java:178) ~[?:1.8.0_261] at > com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XM> LErrorReporter.java:400) ~[?:1.8.0_261] at > com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.report> SchemaErr(XSDHandler.java:4203) ~[?:1.8.0_261] at > com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.report> SchemaFatalError(XSDHandler.java:4182) ~[?:1.8.0_261] at > com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getSch> emaDocument(XSDHandler.java:2201) ~[?:1.8.0_261] at > com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.resolv> eSchema(XSDHandler.java:2129) ~[?:1.8.0_261] at > com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.constr> uctTrees(XSDHandler.java:1130) ~[?:1.8.0_261] at > com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseS> chema(XSDHandler.java:645) ~[?:1.8.0_261]
Solution for this issue should be to set property javax.xml.accessExternalSchema to all, which we tried, also in the code above and also via environment variable and JAVA_OPTIONS property:
JAVA_OPTIONS="-Djavax.xml.accessExternalSchema=all -Djavax.xml.accessExternalDTD=all ..."
Also creating jaxp.properties file in jdk used by the application didn't help:
touch /usr/java/jdk1.8.0_261/jre/lib/jaxp.properties && \
echo "javax.xml.accessExternalSchema = all" > /usr/java/jdk1.8.0_261/jre/lib/jaxp.properties