[java-opensaml] branch main updated: OSJ-307: Support Santuario's XMLParser interface
Brent Putman
putmanb at georgetown.edu
Wed Aug 9 01:51:40 UTC 2023
This is an automated email from the git hooks/post-receive script.
putmanb pushed a commit to branch main
in repository java-opensaml.
View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=c871c2222cc2d3ff4fab16c89b64939c3dfe721f
The following commit(s) were added to refs/heads/main by this push:
new c871c2222 OSJ-307: Support Santuario's XMLParser interface
c871c2222 is described below
commit c871c2222cc2d3ff4fab16c89b64939c3dfe721f
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Tue Aug 8 21:03:28 2023 -0400
OSJ-307: Support Santuario's XMLParser interface
Default to global ParserPool, fallback to an internal one if global
registry not yet initialized and available.
Get maxPoolSize from Configuration Properties.
Adjust class name to be consistent with other Santuario-specific
classes, and move to the package with the other kids.
Add to ApacheXMLSecurityInitializer, with a config prop option to
disable. Default is enabled (for now).
---
.../config/impl/ApacheXMLSecurityInitializer.java | 25 +++++
.../opensaml/xmlsec/impl/SantuarioXMLParser.java | 86 ---------------
.../impl/provider/ApacheSantuarioXMLParser.java | 120 +++++++++++++++++++++
.../provider/ApacheSantuarioXMLParserTest.java} | 9 +-
4 files changed, 150 insertions(+), 90 deletions(-)
diff --git a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/config/impl/ApacheXMLSecurityInitializer.java b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/config/impl/ApacheXMLSecurityInitializer.java
index 30470235e..36134f10f 100644
--- a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/config/impl/ApacheXMLSecurityInitializer.java
+++ b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/config/impl/ApacheXMLSecurityInitializer.java
@@ -14,13 +14,18 @@
package org.opensaml.xmlsec.config.impl;
+import java.util.Properties;
+
import javax.annotation.Nonnull;
import org.apache.xml.security.Init;
+import org.opensaml.core.config.ConfigurationService;
import org.opensaml.core.config.InitializationException;
import org.opensaml.core.config.Initializer;
+import org.opensaml.xmlsec.signature.support.impl.provider.ApacheSantuarioXMLParser;
import org.slf4j.Logger;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.primitive.LoggerFactory;
/**
@@ -28,6 +33,10 @@ import net.shibboleth.shared.primitive.LoggerFactory;
*/
public class ApacheXMLSecurityInitializer implements Initializer {
+ /** Config property for enabling the use of {@link ApacheSantuarioXMLParser}. */
+ @Nonnull @NotEmpty public static final String CONFIG_PROPERTY_XML_PARSER_ENABLE =
+ "opensaml.config.xmlsec.ApacheSantuarioXMLParser.enable";
+
/** Logger. */
@Nonnull private Logger log = LoggerFactory.getLogger(ApacheXMLSecurityInitializer.class);
@@ -38,6 +47,22 @@ public class ApacheXMLSecurityInitializer implements Initializer {
if (System.getProperty(lineBreakPropName) == null) {
System.setProperty(lineBreakPropName, "true");
}
+
+ final Properties props = ConfigurationService.getConfigurationProperties();
+ final boolean enableXMLParser =
+ (props != null) ? Boolean.parseBoolean(props.getProperty(CONFIG_PROPERTY_XML_PARSER_ENABLE, "true"))
+ : true;
+
+ if (enableXMLParser) {
+ final String xmlParserPropName = "org.apache.xml.security.XMLParser";
+ // Don't override if it was set explicitly
+ if (System.getProperty(xmlParserPropName) == null) {
+ log.trace("Enabling use of ApacheSantuarioXMLParser");
+ System.setProperty(xmlParserPropName,
+ "org.opensaml.xmlsec.signature.support.impl.provider.ApacheSantuarioXMLParser");
+ }
+ }
+
if (!Init.isInitialized()) {
log.debug("Initializing Apache XMLSecurity library");
Init.init();
diff --git a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/impl/SantuarioXMLParser.java b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/impl/SantuarioXMLParser.java
deleted file mode 100644
index d0b17f43b..000000000
--- a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/impl/SantuarioXMLParser.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.opensaml.xmlsec.impl;
-
-import java.io.InputStream;
-
-import javax.annotation.Nonnull;
-
-import org.apache.xml.security.parser.XMLParser;
-import org.apache.xml.security.parser.XMLParserException;
-import org.apache.xml.security.utils.XMLUtils;
-import org.opensaml.core.config.InitializationException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-
-import net.shibboleth.shared.component.ComponentInitializationException;
-import net.shibboleth.shared.xml.impl.BasicParserPool;
-
-/**
- * Implementation of Santuario's {@link XMLParser} which simply wraps an instance of {@link BasicParserPool}.
- *
- * <p>
- * Note:
- * </p>
- * <ul>
- * <li>This class is required to have a no-arg constructor.</li>
- * <li>It will fail on any calls where <code>disallowDocTypeDeclarations=false</code>.</li>
- * <li>It is configured into Santuario by setting the class name using system
- * property <code>org.apache.xml.security.XMLParser</code>. For details see: {@link XMLUtils}.</li>
- * <li>The internal parser pool's max pool size may be configured via system property
- * <code>org.opensaml.xmlsec.impl.SantuarioXMLParser.maxPoolSize</code>. The default is: 50</li>
- * </ul>
- */
-public class SantuarioXMLParser implements XMLParser {
-
- /** Logger. */
- @Nonnull final private Logger log = LoggerFactory.getLogger(SantuarioXMLParser.class);
-
- /** Wrapped instance of {@link BasicParserPool}. */
- @Nonnull final private BasicParserPool parserPool;
-
- /**
- * Constructor.
- *
- * @throws InitializationException if the internal {@link BasicParserPool} can not be initialized successfully
- *
- * */
- public SantuarioXMLParser() throws InitializationException {
- try {
- parserPool = new BasicParserPool();
- parserPool.setMaxPoolSize(Integer.getInteger("org.opensaml.xmlsec.impl.SantuarioXMLParser.maxPoolSize", 50));
- parserPool.initialize();
- } catch (final ComponentInitializationException e) {
- throw new InitializationException("Error initializing parser pool", e);
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public Document parse(InputStream inputStream, boolean disallowDocTypeDeclarations) throws XMLParserException {
- if (!disallowDocTypeDeclarations) {
- throw new XMLParserException("This implementation does not support disallowDocTypeDeclarations=false");
- }
-
- try {
- return parserPool.parse(inputStream);
- } catch (final Exception e) {
- log.warn("Fatal error parsing XML InputStream", e);
- throw new XMLParserException(e, "Fatal error parsing XML InputStream");
- }
- }
-
-}
diff --git a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/signature/support/impl/provider/ApacheSantuarioXMLParser.java b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/signature/support/impl/provider/ApacheSantuarioXMLParser.java
new file mode 100644
index 000000000..d3c8473ab
--- /dev/null
+++ b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/signature/support/impl/provider/ApacheSantuarioXMLParser.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opensaml.xmlsec.signature.support.impl.provider;
+
+import java.io.InputStream;
+import java.util.Properties;
+
+import javax.annotation.Nonnull;
+
+import org.apache.xml.security.parser.XMLParser;
+import org.apache.xml.security.parser.XMLParserException;
+import org.apache.xml.security.utils.XMLUtils;
+import org.opensaml.core.config.ConfigurationService;
+import org.opensaml.core.config.InitializationException;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.xml.ParserPool;
+import net.shibboleth.shared.xml.impl.BasicParserPool;
+
+/**
+ * Implementation of Santuario's {@link XMLParser} which simply wraps an instance of {@link ParserPool}.
+ *
+ * <p>
+ * Note:
+ * </p>
+ * <ul>
+ * <li>This class is required to have a no-arg constructor.</li>
+ * <li>It will fail on any calls where <code>disallowDocTypeDeclarations=false</code>.</li>
+ * <li>It is configured into Santuario by setting the class name using system
+ * property <code>org.apache.xml.security.XMLParser</code>. For details see: {@link XMLUtils}.</li>
+ * <li>By default it internally uses the registered global {@link ParserPool} from the {@link ConfigurationService},
+ * if available. If not, then it constructs an internal instance of {@link BasicParserPool}.</li>
+ * <li>The internal parser pool's max pool size may be configured via OpenSAML {@link ConfigurationService} property
+ * <code>{@link #CONFIG_PROPERTY_MAX_POOL_SIZE}</code>. The default is: 50</li>
+ * </ul>
+ */
+public class ApacheSantuarioXMLParser implements XMLParser {
+
+ /** Config property for internal pool's maxPoolSize. */
+ @Nonnull @NotEmpty public static final String CONFIG_PROPERTY_MAX_POOL_SIZE =
+ "opensaml.config.xmlsec.ApacheSantuarioXMLParser.maxPoolSize";
+
+ /** Logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(ApacheSantuarioXMLParser.class);
+
+ /** Wrapped instance of {@link ParserPool}. */
+ @Nonnull private final ParserPool parserPool;
+
+ /**
+ * Constructor.
+ *
+ * @throws InitializationException if the internal {@link BasicParserPool} can not be initialized successfully
+ *
+ * */
+ public ApacheSantuarioXMLParser() throws InitializationException {
+ // Note: We have to do it this way rather than XMLObjectProviderRegistrySupport b/c this class will get
+ // instantiated by Santuario in a static block, and we don't have any control over when that might run vs
+ // OpenSAML init. We shouldn't throw from #ensure(...) in that case.
+ final XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
+ ParserPool globalPool = null;
+ if (registry != null) {
+ globalPool = registry.getParserPool();
+ }
+ if (globalPool != null) {
+ parserPool = globalPool;
+ log.trace("Configured parser pool as global ParserPool");
+ } else {
+ try {
+ final Properties props = ConfigurationService.getConfigurationProperties();
+ final int maxPoolSize =
+ (props != null) ? Integer.parseUnsignedInt(
+ props.getProperty(CONFIG_PROPERTY_MAX_POOL_SIZE, "50"))
+ : 50;
+
+ final BasicParserPool basicPool = new BasicParserPool();
+ basicPool.setMaxPoolSize(maxPoolSize);
+ basicPool.initialize();
+ parserPool = basicPool;
+ log.trace("Configured parser pool as internally-constructed BasicParserPool with maxPoolSize: {}",
+ maxPoolSize);
+ } catch (final ComponentInitializationException e) {
+ throw new InitializationException("Error initializing internal BasicParserPool", e);
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Document parse(final InputStream inputStream, final boolean disallowDocTypeDeclarations)
+ throws XMLParserException {
+ if (!disallowDocTypeDeclarations) {
+ throw new XMLParserException("This implementation does not support disallowDocTypeDeclarations=false");
+ }
+
+ try {
+ return parserPool.parse(inputStream);
+ } catch (final Exception e) {
+ log.warn("Fatal error parsing XML InputStream", e);
+ throw new XMLParserException(e, "Fatal error parsing XML InputStream");
+ }
+ }
+
+}
diff --git a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/impl/SantuarioXMLParserTest.java b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/signature/support/impl/provider/ApacheSantuarioXMLParserTest.java
similarity index 87%
rename from opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/impl/SantuarioXMLParserTest.java
rename to opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/signature/support/impl/provider/ApacheSantuarioXMLParserTest.java
index d73abced1..35caf0d7b 100644
--- a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/impl/SantuarioXMLParserTest.java
+++ b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/signature/support/impl/provider/ApacheSantuarioXMLParserTest.java
@@ -12,25 +12,26 @@
* limitations under the License.
*/
-package org.opensaml.xmlsec.impl;
+package org.opensaml.xmlsec.signature.support.impl.provider;
import java.io.IOException;
import java.io.InputStream;
import org.apache.xml.security.parser.XMLParserException;
import org.opensaml.core.config.InitializationException;
+import org.opensaml.core.testing.XMLObjectBaseTestCase;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
-public class SantuarioXMLParserTest {
+public class ApacheSantuarioXMLParserTest extends XMLObjectBaseTestCase {
- private SantuarioXMLParser parser;
+ private ApacheSantuarioXMLParser parser;
@BeforeClass
public void setUpClass() throws InitializationException {
- parser = new SantuarioXMLParser();
+ parser = new ApacheSantuarioXMLParser();
}
@Test
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list