summaryrefslogtreecommitdiff
path: root/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverFactory.java
diff options
context:
space:
mode:
authorThomas <thomas.lenz@egiz.gv.at>2020-02-02 19:32:21 +0100
committerThomas <thomas.lenz@egiz.gv.at>2020-02-02 19:32:21 +0100
commit41ea2fdf782cd64d7d29f73c2e83f9c255810818 (patch)
tree9710ca3937ae82391c6a2a0e5176923e0a49a5af /eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverFactory.java
parentd41afe91ee59daf6b5f5037cecac52900fe2ccb2 (diff)
downloadEAAF-Components-41ea2fdf782cd64d7d29f73c2e83f9c255810818.tar.gz
EAAF-Components-41ea2fdf782cd64d7d29f73c2e83f9c255810818.tar.bz2
EAAF-Components-41ea2fdf782cd64d7d29f73c2e83f9c255810818.zip
some more OpenSAML3 refactoring stuff
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverFactory.java')
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverFactory.java271
1 files changed, 271 insertions, 0 deletions
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverFactory.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverFactory.java
new file mode 100644
index 00000000..f548bc7b
--- /dev/null
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverFactory.java
@@ -0,0 +1,271 @@
+package at.gv.egiz.eaaf.modules.pvp2.impl.metadata;
+
+import java.io.IOException;
+import java.util.Timer;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.PostConstruct;
+import javax.net.ssl.SSLHandshakeException;
+
+import org.apache.http.client.HttpClient;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.saml.metadata.resolver.ExtendedRefreshableMetadataResolver;
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilter;
+import org.opensaml.saml.metadata.resolver.impl.HTTPMetadataResolver;
+import org.opensaml.saml.metadata.resolver.impl.ResourceBackedMetadataResolver;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ResourceLoader;
+
+import at.gv.egiz.components.spring.api.IDestroyableObject;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.impl.utils.FileUtils;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SchemaValidationException;
+import at.gv.egiz.eaaf.modules.pvp2.exception.SignatureValidationException;
+import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.OpenSaml3ResourceAdapter;
+import lombok.extern.slf4j.Slf4j;
+import net.shibboleth.utilities.java.support.resource.Resource;
+import net.shibboleth.utilities.java.support.xml.ParserPool;
+
+@Slf4j
+public class PvpMetadataResolverFactory implements IDestroyableObject {
+
+ private static final String URI_PREFIX_HTTP = "http:";
+ private static final String URI_PREFIX_HTTPS = "https:";
+
+ private Timer timer = null;
+
+ @Autowired private IConfiguration authConfig;
+ @Autowired private ResourceLoader resourceLoader;
+
+ /**
+ * Create a single SAML2 metadata provider by using the default OpenSAML3 parser-pool.
+ *
+ * @param metadataLocation where the metadata should be loaded, but never null.
+ * If the location starts with http(s):, than a http
+ * based metadata provider is used. If the location
+ * starts with file:, than a filesystem based metadata
+ * provider is used
+ * @param filter Filters, which should be used to validate the
+ * metadata
+ * @param idForLogging Id, which is used for Logging
+ * @param httpClient Apache commons 4.x http client
+ *
+ * @return SAML2 Metadata Provider, or null if the metadata provider can not
+ * initialized
+ */
+ @Nullable
+ public IPvp2MetadataProvider createMetadataProvider(@Nonnull final String metadataLocation,
+ @Nullable final MetadataFilter filter, @Nonnull final String idForLogging,
+ @Nullable final HttpClient httpClient) {
+ return createMetadataProvider(metadataLocation, filter, idForLogging,
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ httpClient);
+
+ }
+
+ /**
+ * Create a single SAML2 metadata provider.
+ *
+ * @param metadataLocation where the metadata should be loaded, but never null.
+ * If the location starts with http(s):, than a http
+ * based metadata provider is used. If the location
+ * starts with file:, than a filesystem based metadata
+ * provider is used
+ * @param filter Filters, which should be used to validate the
+ * metadata
+ * @param idForLogging Id, which is used for Logging
+ * @param httpClient Apache commons 4.x http client
+ *
+ * @return SAML2 Metadata Provider, or null if the metadata provider can not
+ * initialized
+ */
+ @Nullable
+ public IPvp2MetadataProvider createMetadataProvider(@Nonnull final String metadataLocation,
+ @Nullable final MetadataFilter filter, @Nonnull final String idForLogging,
+ @Nullable final ParserPool pool, @Nullable final HttpClient httpClient) {
+
+ ExtendedRefreshableMetadataResolver internalProvider = null;
+
+ if (metadataLocation.startsWith(URI_PREFIX_HTTP)
+ || metadataLocation.startsWith(URI_PREFIX_HTTPS)) {
+ if (httpClient != null) {
+ internalProvider = createNewHttpMetaDataProvider(metadataLocation, filter, idForLogging, timer, pool,
+ httpClient);
+ } else {
+ log.warn("Can not load http(s) based SAML2 metadata without a HTTP client");
+
+ }
+
+ } else {
+ String absoluteMetadataLocation;
+ try {
+ absoluteMetadataLocation =
+ FileUtils.makeAbsoluteUrl(metadataLocation, authConfig.getConfigurationRootDirectory());
+
+ org.springframework.core.io.Resource resource = resourceLoader.getResource(absoluteMetadataLocation);
+ if (resource.exists()) {
+ internalProvider = createNewFileSystemMetaDataProvider(
+ new OpenSaml3ResourceAdapter(resource),
+ filter, idForLogging, timer,
+ pool);
+ } else {
+ log.warn(
+ "SAML2 metadata file: " + absoluteMetadataLocation + " not found or not exist");
+
+ }
+
+
+ } catch (final IOException e) {
+ log.warn("SAML2 metadata URL is invalid: " + metadataLocation, e);
+
+ }
+ }
+
+ if (internalProvider != null) {
+ return new PvpMetadataResolverAdapter(internalProvider);
+
+ } else {
+ log.warn("SAML2 metadata has an unsupported metadata location prefix: " + metadataLocation);
+ return null;
+
+ }
+
+ }
+
+ /**
+ * Create a single SAML2 filesystem based metadata provider.
+ *
+ * @param metadataFile File, where the metadata should be loaded
+ * @param filter Filters, which should be used to validate the metadata
+ * @param idForLogging Id, which is used for Logging
+ * @param timer {@link Timer} which is used to schedule metadata refresh
+ * operations
+ * @param pool
+ *
+ * @return SAML2 Metadata Provider
+ * @throws IOException
+ */
+ private ExtendedRefreshableMetadataResolver createNewFileSystemMetaDataProvider(final Resource metadataFile,
+ final MetadataFilter filter, final String idForLogging, final Timer timer,
+ final ParserPool pool) throws IOException {
+ ResourceBackedMetadataResolver fileSystemResolver = null;
+ try {
+ //fileSystemResolver = new FilesystemMetadataResolver(timer, metadataFile);
+
+ fileSystemResolver = new ResourceBackedMetadataResolver(timer, metadataFile);
+
+ if (pool != null) {
+ fileSystemResolver.setParserPool(pool);
+
+ } else {
+ fileSystemResolver.setParserPool(
+ XMLObjectProviderRegistrySupport.getParserPool());
+
+ }
+ fileSystemResolver.setRequireValidMetadata(true);
+ fileSystemResolver.setMinRefreshDelay(1000 * 60 * 15); // 15 minutes
+ fileSystemResolver.setMaxRefreshDelay(1000 * 60 * 60 * 24); // 24 hours
+
+ fileSystemResolver.setMetadataFilter(filter);
+ fileSystemResolver.initialize();
+ fileSystemResolver.setId(metadataFile.getURI().toASCIIString());
+
+ fileSystemResolver.setRequireValidMetadata(true);
+
+ return fileSystemResolver;
+
+ } catch (final Exception e) {
+ log.warn("Failed to load Metadata file for " + idForLogging + "[ " + "File: "
+ + metadataFile.getURI().toASCIIString() + " Msg: " + e.getMessage() + " ]", e);
+
+ log.warn("Can not initialize SAML2 metadata provider from filesystem: "
+ + metadataFile.getURI().toASCIIString() + " Reason: " + e.getMessage(), e);
+
+ if (fileSystemResolver != null) {
+ fileSystemResolver.destroy();
+
+ }
+
+ }
+
+ return null;
+
+ }
+
+ /**
+ * Create a single SAML2 HTTP metadata provider.
+ *
+ * @param metadataUrl URL, where the metadata should be loaded
+ * @param filter Filters, which should be used to validate the metadata
+ * @param idForLogging Id, which is used for Logging
+ * @param timer {@link Timer} which is used to schedule metadata refresh
+ * operations
+ * @param pool
+ *
+ * @return SAML2 Metadata Provider
+ */
+ private ExtendedRefreshableMetadataResolver createNewHttpMetaDataProvider(final String metadataUrl,
+ final MetadataFilter filter, final String idForLogging, final Timer timer,
+ final ParserPool pool, final HttpClient httpClient) {
+ HTTPMetadataResolver httpMetadataResolver = null;
+ try {
+ httpMetadataResolver = new HTTPMetadataResolver(timer, httpClient, metadataUrl);
+ httpMetadataResolver.setParserPool(pool);
+ httpMetadataResolver.setRequireValidMetadata(true);
+ httpMetadataResolver.setMinRefreshDelay(1000 * 60 * 15); // 15 minutes
+ httpMetadataResolver.setMaxRefreshDelay(1000 * 60 * 60 * 24); // 24 hours
+ // httpProvider.setRefreshDelayFactor(0.1F);
+
+ httpMetadataResolver.setMetadataFilter(filter);
+ httpMetadataResolver.setId(metadataUrl);
+ httpMetadataResolver.initialize();
+
+ httpMetadataResolver.setRequireValidMetadata(true);
+
+ return httpMetadataResolver;
+
+ } catch (final Throwable e) {
+ if (e.getCause() != null && e.getCause().getCause() instanceof SSLHandshakeException) {
+ log.warn("SSL-Server certificate for metadata " + metadataUrl + " not trusted.", e);
+
+ }
+ if (e.getCause() != null && e.getCause().getCause() instanceof SignatureValidationException) {
+ log.warn("Signature verification for metadata" + metadataUrl + " FAILED.", e);
+
+ }
+ if (e.getCause() != null && e.getCause().getCause() instanceof SchemaValidationException) {
+ log.warn("Schema validation for metadata " + metadataUrl + " FAILED.", e);
+ }
+
+ log.warn("Failed to load Metadata file for " + idForLogging + "[ " + e.getMessage() + " ]",
+ e);
+
+ if (httpMetadataResolver != null) {
+ log.debug("Destroy failed Metadata provider");
+ httpMetadataResolver.destroy();
+
+ }
+
+ }
+
+ return null;
+ }
+
+ @Override
+ public void fullyDestroy() {
+ if (timer != null) {
+ log.info("Stopping timer-thread for PVP metadata resolver ... ");
+ timer.cancel();
+ }
+ }
+
+ @PostConstruct
+ private void initialize() {
+ log.info("Initializing timer-thread for PVP metadata resolver ... ");
+ timer = new Timer("PVP metadata-resolver refresh");
+
+ }
+
+}