From e7610325ee2f1d1f4e97e1e7a9b212e692836b5a Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Tue, 4 Feb 2020 17:37:34 +0100 Subject: first stable version that uses OpenSAML 3.x --- .../metadata/AbstractChainingMetadataProvider.java | 334 ++++++++++----------- 1 file changed, 160 insertions(+), 174 deletions(-) (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java') diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java index 3fc675e9..8a20b932 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java @@ -27,12 +27,17 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.UUID; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.naming.ConfigurationException; +import at.gv.egiz.components.spring.api.IDestroyableObject; +import at.gv.egiz.eaaf.core.api.IGarbageCollectorProcessing; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider; + import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.opensaml.core.criterion.EntityIdCriterion; @@ -43,11 +48,6 @@ import org.opensaml.saml.metadata.resolver.filter.MetadataFilter; import org.opensaml.saml.metadata.resolver.impl.AbstractMetadataResolver; import org.opensaml.saml.saml2.metadata.EntityDescriptor; -import at.gv.egiz.components.spring.api.IDestroyableObject; -import at.gv.egiz.eaaf.core.api.IGarbageCollectorProcessing; -import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider; import lombok.extern.slf4j.Slf4j; import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements; import net.shibboleth.utilities.java.support.component.IdentifiedComponent; @@ -55,10 +55,13 @@ import net.shibboleth.utilities.java.support.resolver.CriteriaSet; import net.shibboleth.utilities.java.support.resolver.ResolverException; @Slf4j -public abstract class AbstractChainingMetadataProvider implements IGarbageCollectorProcessing, IRefreshableMetadataProvider, +public abstract class AbstractChainingMetadataProvider implements IGarbageCollectorProcessing, + IRefreshableMetadataProvider, IDestroyableObject, IPvp2MetadataProvider, ClearableMetadataResolver { - - @Nonnull @NonnullElements private final List internalResolvers; + + @Nonnull + @NonnullElements + private final List internalResolvers; private DateTime lastRefeshTimestamp; private boolean lastRefeshSuccessful; private static Object mutex = new Object(); @@ -72,7 +75,6 @@ public abstract class AbstractChainingMetadataProvider implements IGarbageCollec } - /* * (non-Javadoc) * @@ -104,8 +106,6 @@ public abstract class AbstractChainingMetadataProvider implements IGarbageCollec } - - @Override public synchronized boolean refreshMetadataProvider(final String entityId) { try { @@ -130,7 +130,7 @@ public abstract class AbstractChainingMetadataProvider implements IGarbageCollec // check if MetadataProvider is actually loaded final MetadataResolver loadedResover = actuallyLoadedResolver.get(metadataUrl); if (loadedResover instanceof RefreshableMetadataResolver) { - ((RefreshableMetadataResolver)loadedResover).refresh(); + ((RefreshableMetadataResolver) loadedResover).refresh(); log.info("SAML2 metadata for service provider: " + entityId + " is refreshed."); return true; @@ -162,30 +162,29 @@ public abstract class AbstractChainingMetadataProvider implements IGarbageCollec * */ public void internalDestroy() { - log.info("Destroying chained metadata resolvers ..."); + log.info("Destroying chained metadata resolvers ..."); - for (final MetadataResolver resolver : internalResolvers) { - destroyMetadataResolver(resolver); - } + for (final MetadataResolver resolver : internalResolvers) { + destroyMetadataResolver(resolver); + } - internalResolvers.clear(); + internalResolvers.clear(); } - /** {@inheritDoc} */ - @Override + @Override public final MetadataFilter getMetadataFilter() { - log.warn("{} does NOT support {}", AbstractChainingMetadataProvider.class.getName(), - MetadataFilter.class.getName()); - return null; + log.warn("{} does NOT support {}", AbstractChainingMetadataProvider.class.getName(), + MetadataFilter.class.getName()); + return null; } - /** {@inheritDoc} */ - @Override + @Override public final void setMetadataFilter(final MetadataFilter newFilter) { log.warn("{} does NOT support {}", AbstractChainingMetadataProvider.class.getName(), MetadataFilter.class.getName()); - throw new UnsupportedOperationException("Metadata filters are not supported on AbstractChainingMetadataProvider"); + throw new UnsupportedOperationException( + "Metadata filters are not supported on AbstractChainingMetadataProvider"); } /* @@ -221,17 +220,17 @@ public abstract class AbstractChainingMetadataProvider implements IGarbageCollec } @Override - @Nullable + @Nullable public final EntityDescriptor resolveSingle(@Nullable final CriteriaSet criteria) throws ResolverException { for (final MetadataResolver resolver : internalResolvers) { try { - final EntityDescriptor descriptors = resolver.resolveSingle(criteria); - if (descriptors != null) { - return descriptors; - } + final EntityDescriptor descriptors = resolver.resolveSingle(criteria); + if (descriptors != null) { + return descriptors; + } } catch (final ResolverException e) { - continue; + continue; } @@ -242,87 +241,90 @@ public abstract class AbstractChainingMetadataProvider implements IGarbageCollec } @Override - @Nonnull - public final Iterable resolve(@Nullable final CriteriaSet criteria) throws ResolverException { - for (final MetadataResolver resolver : internalResolvers) { - try { - final Iterable descriptors = resolver.resolve(criteria); - if (descriptors != null && descriptors.iterator().hasNext()) { - return descriptors; - - } - - } catch (final ResolverException e) { - continue; - - } + @Nonnull + public final Iterable resolve(@Nullable final CriteriaSet criteria) + throws ResolverException { + for (final MetadataResolver resolver : internalResolvers) { + try { + final Iterable descriptors = resolver.resolve(criteria); + if (descriptors != null && descriptors.iterator().hasNext()) { + return descriptors; + + } + + } catch (final ResolverException e) { + continue; + } + } - return Collections.emptyList(); + return Collections.emptyList(); } - + @Override public final void clear() throws ResolverException { - for (final MetadataResolver resolver : internalResolvers) { - if (resolver instanceof ClearableMetadataResolver) { - ((ClearableMetadataResolver) resolver).clear(); - } + for (final MetadataResolver resolver : internalResolvers) { + if (resolver instanceof ClearableMetadataResolver) { + ((ClearableMetadataResolver) resolver).clear(); } + } } @Override public final void clear(String entityID) throws ResolverException { - for (final MetadataResolver resolver : internalResolvers) { - if (resolver instanceof ClearableMetadataResolver) { - ((ClearableMetadataResolver) resolver).clear(entityID); - } + for (final MetadataResolver resolver : internalResolvers) { + if (resolver instanceof ClearableMetadataResolver) { + ((ClearableMetadataResolver) resolver).clear(entityID); } + } } - @Override final public void refresh() throws ResolverException { - this.lastRefeshSuccessful = false; - for (final MetadataResolver resolver : internalResolvers) { - if (resolver instanceof RefreshableMetadataResolver) { - ((RefreshableMetadataResolver) resolver).refresh(); - - } + @Override + public final void refresh() throws ResolverException { + this.lastRefeshSuccessful = false; + for (final MetadataResolver resolver : internalResolvers) { + if (resolver instanceof RefreshableMetadataResolver) { + ((RefreshableMetadataResolver) resolver).refresh(); + } - - this.lastRefeshTimestamp = DateTime.now(); - this.lastRefeshSuccessful = true; + } + + this.lastRefeshTimestamp = DateTime.now(); + this.lastRefeshSuccessful = true; } @Override - @Nullable public DateTime getLastUpdate() { - DateTime ret = null; - for (final MetadataResolver resolver : internalResolvers) { - if (resolver instanceof RefreshableMetadataResolver) { - final DateTime lastUpdate = ((RefreshableMetadataResolver) resolver).getLastUpdate(); - if (ret == null || ret.isBefore(lastUpdate)) { - ret = lastUpdate; - } - } + @Nullable + public DateTime getLastUpdate() { + DateTime ret = null; + for (final MetadataResolver resolver : internalResolvers) { + if (resolver instanceof RefreshableMetadataResolver) { + final DateTime lastUpdate = ((RefreshableMetadataResolver) resolver).getLastUpdate(); + if (ret == null || ret.isBefore(lastUpdate)) { + ret = lastUpdate; + } } - - return ret; + } + + return ret; } @Override - @Nullable final public DateTime getLastRefresh() { - DateTime ret = null; - for (final MetadataResolver resolver : internalResolvers) { - if (resolver instanceof RefreshableMetadataResolver) { - final DateTime lastRefresh = ((RefreshableMetadataResolver) resolver).getLastRefresh(); - if (ret == null || ret.isBefore(lastRefresh)) { - ret = lastRefresh; - } - } + @Nullable + public final DateTime getLastRefresh() { + DateTime ret = null; + for (final MetadataResolver resolver : internalResolvers) { + if (resolver instanceof RefreshableMetadataResolver) { + final DateTime lastRefresh = ((RefreshableMetadataResolver) resolver).getLastRefresh(); + if (ret == null || ret.isBefore(lastRefresh)) { + ret = lastRefresh; + } } - - return ret; + } + + return ret; } - - + /** * Get the URL to metadata for a specific entityID. * @@ -354,103 +356,92 @@ public abstract class AbstractChainingMetadataProvider implements IGarbageCollec protected abstract List getAllMetadataUrlsFromConfiguration() throws EaafConfigurationException; - /** * Get a Id for this metadata provider. - * + * * @return */ @Nonnull protected abstract String getMetadataProviderId(); - + protected final MetadataResolver getMetadataResolver() { log.warn("{} does NOT support 'getMetadataResolver'", AbstractChainingMetadataProvider.class.getName()); return null; - + } - + private Map getAllActuallyLoadedResolvers() { final Map loadedproviders = new HashMap<>(); // make a Map of all actually loaded HTTPMetadataProvider for (final MetadataResolver resolver : internalResolvers) { - if (resolver instanceof IdentifiedComponent) { - loadedproviders.put(((IdentifiedComponent) resolver).getId(), resolver); - - } else { - final String uuid = UUID.randomUUID().toString(); - loadedproviders.put(uuid, resolver); - log.debug("MetadatenResolver is not of type: {}. Mark it with id: {}", - IdentifiedComponent.class.getSimpleName(), uuid); + loadedproviders.put(((IdentifiedComponent) resolver).getId(), resolver); - } } return loadedproviders; } private void addAndRemoveMetadataProvider() throws EaafConfigurationException { - log.info("EAAF chaining metadata resolver starting internal managment task .... "); + log.info("EAAF chaining metadata resolver starting internal managment task .... "); + + /* + * OpenSAML ChainingMetadataProvider can not remove a MetadataProvider + * (UnsupportedOperationException) The ChainingMetadataProvider use internal a + * unmodifiableList to hold all registrated MetadataProviders. + */ + final Map providersinuse = new HashMap<>(); + + // get all actually loaded metadata providers + final Map loadedproviders = getAllActuallyLoadedResolvers(); + + /* + * TODO: maybe add metadata provider destroy after timeout. But could be a + * problem if one Metadataprovider load an EntitiesDescriptor with more the + * multiple EntityDescriptors. If one of this EntityDesciptors are expired the + * full EntitiesDescriptor is removed. + * + * Timeout requires a better solution in this case! + */ + + // load all SAML2 SPs form configuration and + // compare actually loaded Providers with configured SAML2 SPs + final List allMetadataUrls = getAllMetadataUrlsFromConfiguration(); + + final Iterator metadataUrlInterator = allMetadataUrls.iterator(); + while (metadataUrlInterator.hasNext()) { + final String metadataurl = metadataUrlInterator.next(); + try { + if (StringUtils.isNotEmpty(metadataurl) + && loadedproviders.containsKey(metadataurl)) { + // SAML2 SP is actually loaded, to nothing + providersinuse.put(metadataurl, loadedproviders.get(metadataurl)); + loadedproviders.remove(metadataurl); + + } + } catch (final Throwable e) { + log.error("Failed to add Metadata (unhandled reason: " + e.getMessage(), e); + + } + } + + // remove all actually loaded MetadataProviders with are not in ConfigurationDB + // any more + final Collection notusedproviders = loadedproviders.values(); + for (final MetadataResolver resolver : notusedproviders) { + log.info("Remove not used MetadataProvider with MetadataURL " + resolver.getId()); + destroyMetadataResolver(resolver); + internalResolvers.remove(resolver); /* * OpenSAML ChainingMetadataProvider can not remove a MetadataProvider * (UnsupportedOperationException) The ChainingMetadataProvider use internal a * unmodifiableList to hold all registrated MetadataProviders. */ - final Map providersinuse = new HashMap<>(); + // chainProvider.removeMetadataProvider(provider); - // get all actually loaded metadata providers - final Map loadedproviders = getAllActuallyLoadedResolvers(); - - /* - * TODO: maybe add metadata provider destroy after timeout. But could be a - * problem if one Metadataprovider load an EntitiesDescriptor with more the - * multiple EntityDescriptors. If one of this EntityDesciptors are expired the - * full EntitiesDescriptor is removed. - * - * Timeout requires a better solution in this case! - */ - - // load all SAML2 SPs form configuration and - // compare actually loaded Providers with configured SAML2 SPs - final List allMetadataUrls = getAllMetadataUrlsFromConfiguration(); - - final Iterator metadataUrlInterator = allMetadataUrls.iterator(); - while (metadataUrlInterator.hasNext()) { - final String metadataurl = metadataUrlInterator.next(); - try { - if (StringUtils.isNotEmpty(metadataurl) - && loadedproviders.containsKey(metadataurl)) { - // SAML2 SP is actually loaded, to nothing - providersinuse.put(metadataurl, loadedproviders.get(metadataurl)); - loadedproviders.remove(metadataurl); - - } - } catch (final Throwable e) { - log.error("Failed to add Metadata (unhandled reason: " + e.getMessage(), e); - - } - } - - - // remove all actually loaded MetadataProviders with are not in ConfigurationDB - // any more - final Collection notusedproviders = loadedproviders.values(); - for (final MetadataResolver resolver : notusedproviders) { - log.info("Remove not used MetadataProvider with MetadataURL " + resolver.getId()); - destroyMetadataResolver(resolver); - internalResolvers.remove(resolver); - - /* - * OpenSAML ChainingMetadataProvider can not remove a MetadataProvider - * (UnsupportedOperationException) The ChainingMetadataProvider use internal a - * unmodifiableList to hold all registrated MetadataProviders. - */ - // chainProvider.removeMetadataProvider(provider); - - - } + } } @@ -474,39 +465,34 @@ public abstract class AbstractChainingMetadataProvider implements IGarbageCollec } } - - @Override public DateTime getLastSuccessfulRefresh() { return this.lastRefeshTimestamp; - - } + } @Override public Boolean wasLastRefreshSuccess() { return this.lastRefeshSuccessful; - - } - - - /** {@inheritDoc} */ - @Override public boolean isRequireValidMetadata() { - log.warn("Attempt to access unsupported requireValidMetadata property on ChainingMetadataResolver"); - return false; } - /** {@inheritDoc} */ - @Override public void setRequireValidMetadata(final boolean requireValidMetadata) { - throw new UnsupportedOperationException("Setting requireValidMetadata is not supported on chaining resolver"); + @Override + public boolean isRequireValidMetadata() { + log.warn("Attempt to access unsupported requireValidMetadata property on ChainingMetadataResolver"); + return false; } + @Override + public void setRequireValidMetadata(final boolean requireValidMetadata) { + throw new UnsupportedOperationException( + "Setting requireValidMetadata is not supported on chaining resolver"); + } @Override public String getId() { return getMetadataProviderId(); - + } - + } -- cgit v1.2.3