summaryrefslogtreecommitdiff
path: root/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2020-01-31 20:41:54 +0100
committerThomas Lenz <thomas.lenz@egiz.gv.at>2020-01-31 20:41:54 +0100
commitd41afe91ee59daf6b5f5037cecac52900fe2ccb2 (patch)
tree3a19e1818d276d701574758ce6166b2f3a7e2030 /eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java
parent0cf9926282ba4aa46bad3f4e8020cec72683492f (diff)
downloadEAAF-Components-d41afe91ee59daf6b5f5037cecac52900fe2ccb2.tar.gz
EAAF-Components-d41afe91ee59daf6b5f5037cecac52900fe2ccb2.tar.bz2
EAAF-Components-d41afe91ee59daf6b5f5037cecac52900fe2ccb2.zip
a lot of more OpenSAML3 refactoring staff
This version is also NOT stable!
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java')
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java253
1 files changed, 105 insertions, 148 deletions
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 4a9bb89a..ec59b1df 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
@@ -21,48 +21,59 @@ package at.gv.egiz.eaaf.modules.pvp2.impl.metadata;
import java.io.IOException;
import java.security.cert.CertificateException;
-import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Timer;
+import java.util.UUID;
+import javax.annotation.Nonnull;
+import javax.naming.ConfigurationException;
import javax.xml.namespace.QName;
-import org.apache.commons.lang3.StringUtils;
-import org.opensaml.saml2.metadata.EntitiesDescriptor;
-import org.opensaml.saml2.metadata.EntityDescriptor;
-import org.opensaml.saml2.metadata.RoleDescriptor;
-import org.opensaml.saml2.metadata.provider.ChainingMetadataProvider;
-import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider;
-import org.opensaml.saml2.metadata.provider.MetadataFilter;
-import org.opensaml.saml2.metadata.provider.MetadataProvider;
-import org.opensaml.saml2.metadata.provider.MetadataProviderException;
-import org.opensaml.saml2.metadata.provider.ObservableMetadataProvider;
-import org.opensaml.xml.XMLObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
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.IPvpMetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider;
-public abstract class AbstractChainingMetadataProvider extends SimpleMetadataProvider
- implements ObservableMetadataProvider, IGarbageCollectorProcessing,
- IRefreshableMetadataProvider, IDestroyableObject, IPvpMetadataProvider {
+import org.apache.commons.lang3.StringUtils;
+import org.opensaml.core.criterion.EntityIdCriterion;
+import org.opensaml.saml.metadata.resolver.ClearableMetadataResolver;
+import org.opensaml.saml.metadata.resolver.MetadataResolver;
+import org.opensaml.saml.metadata.resolver.RefreshableMetadataResolver;
+import org.opensaml.saml.metadata.resolver.filter.MetadataFilter;
+import org.opensaml.saml.metadata.resolver.impl.AbstractMetadataResolver;
+import org.opensaml.saml.saml2.metadata.EntitiesDescriptor;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.RoleDescriptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.component.IdentifiedComponent;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+public abstract class AbstractChainingMetadataProvider extends SimpleMetadataResolver
+ implements IGarbageCollectorProcessing, IRefreshableMetadataProvider, IDestroyableObject, IPvp2MetadataProvider,
+ RefreshableMetadataResolver, ClearableMetadataResolver {
private static final Logger log = LoggerFactory.getLogger(AbstractChainingMetadataProvider.class);
- private MetadataProvider internalProvider = null;
+ @Nonnull @NonnullElements private final List<MetadataResolver> internalResolvers;
private static Object mutex = new Object();
private Timer timer = null;
+ /**
+ * Build a chaining metadata resolver that requires valid metadata.
+ *
+ */
public AbstractChainingMetadataProvider() {
- internalProvider = new ChainingMetadataProvider();
+ internalResolvers = Collections.synchronizedList(Collections.emptyList());
}
@@ -102,30 +113,34 @@ public abstract class AbstractChainingMetadataProvider extends SimpleMetadataPro
}
+
+
@Override
- public synchronized boolean refreshMetadataProvider(final String entityID) {
+ public synchronized boolean refreshMetadataProvider(final String entityId) {
try {
// check if metadata provider is already loaded
try {
- if (internalProvider.getEntityDescriptor(entityID) != null) {
+ if (resolveEntityDescripor(entityId) != null) {
return true;
+
}
- } catch (final MetadataProviderException e) {
- log.debug("Metadata for EntityId: {} is not valid. Starting refresh ... ", entityID);
+ } catch (final ResolverException e) {
+ log.debug("Metadata for EntityId: {} is not valid. Starting refresh ... ", entityId);
}
// reload metadata provider
- final String metadataUrl = getMetadataUrl(entityID);
+ final String metadataUrl = getMetadataUrl(entityId);
if (StringUtils.isNotEmpty(metadataUrl)) {
- final Map<String, HTTPMetadataProvider> actuallyLoadedProviders =
- getAllActuallyLoadedProviders();
+ final Map<String, MetadataResolver> actuallyLoadedResolver =
+ getAllActuallyLoadedResolvers();
// check if MetadataProvider is actually loaded
- if (actuallyLoadedProviders.containsKey(metadataUrl)) {
- actuallyLoadedProviders.get(metadataUrl).refresh();
- log.info("SAML2 metadata for service provider: " + entityID + " is refreshed.");
+ final MetadataResolver loadedResover = actuallyLoadedResolver.get(metadataUrl);
+ if (loadedResover instanceof RefreshableMetadataResolver) {
+ ((RefreshableMetadataResolver)loadedResover).refresh();
+ log.info("SAML2 metadata for service provider: " + entityId + " is refreshed.");
return true;
} else {
@@ -134,32 +149,20 @@ public abstract class AbstractChainingMetadataProvider extends SimpleMetadataPro
timer = new Timer(true);
}
- final ChainingMetadataProvider chainProvider =
- (ChainingMetadataProvider) internalProvider;
- chainProvider.addMetadataProvider(createNewMetadataProvider(entityID));
+ internalResolvers.add(createNewMetadataProvider(metadataUrl));
- emitChangeEvent();
- log.info("SAML2 metadata for service provider: " + entityID + " is added.");
+ log.info("SAML2 metadata for service provider: " + entityId + " is added.");
return true;
}
} else {
log.debug(
- "Can not refresh SAML2 metadata: NO SAML2 metadata URL for SP with Id: " + entityID);
+ "Can not refresh SAML2 metadata: NO SAML2 metadata URL for SP with Id: " + entityId);
}
- } catch (final MetadataProviderException e) {
- log.warn("Refresh SAML2 metadata for service provider: " + entityID + " FAILED.", e);
-
- } catch (final IOException e) {
- log.warn("Refresh SAML2 metadata for service provider: " + entityID + " FAILED.", e);
-
- } catch (final EaafConfigurationException e) {
- log.warn("Refresh SAML2 metadata for service provider: " + entityID + " FAILED.", e);
-
- } catch (final CertificateException e) {
- log.warn("Refresh SAML2 metadata for service provider: " + entityID + " FAILED.", e);
+ } catch (final IOException | ResolverException | EaafConfigurationException | CertificateException e) {
+ log.warn("Refresh SAML2 metadata for service provider: " + entityId + " FAILED.", e);
}
@@ -172,55 +175,20 @@ public abstract class AbstractChainingMetadataProvider extends SimpleMetadataPro
*
*/
public void internalDestroy() {
- if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) {
- log.info("Destrorying PVP-Authentication MetaDataProvider.");
- final ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider;
-
- final List<MetadataProvider> providers = chainProvider.getProviders();
- for (final MetadataProvider provider : providers) {
- if (provider instanceof HTTPMetadataProvider) {
- final HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider;
- log.debug("Destroy HTTPMetadataProvider +" + httpprovider.getMetadataURI());
- httpprovider.destroy();
+ log.info("Destroying chained metadata resolvers ...");
- } else {
- log.warn("MetadataProvider can not be destroyed.");
- }
+ for (final MetadataResolver resolver : internalResolvers) {
+ destroyMetadataResolver(resolver);
}
- internalProvider = new ChainingMetadataProvider();
+ internalResolvers.clear();
if (timer != null) {
timer.cancel();
}
- } else {
- log.warn(
- "ReInitalize MOAMetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy");
- }
}
- /*
- * (non-Javadoc)
- *
- * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#
- * requireValidMetadata()
- */
- @Override
- public boolean requireValidMetadata() {
- return internalProvider.requireValidMetadata();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#
- * setRequireValidMetadata (boolean)
- */
- @Override
- public void setRequireValidMetadata(final boolean requireValidMetadata) {
- internalProvider.setRequireValidMetadata(requireValidMetadata);
- }
/*
* (non-Javadoc)
@@ -359,18 +327,6 @@ public abstract class AbstractChainingMetadataProvider extends SimpleMetadataPro
return result;
}
- /*
- * (non-Javadoc)
- *
- * @see
- * org.opensaml.saml2.metadata.provider.ObservableMetadataProvider#getObservers(
- * )
- */
- @Override
- public List<Observer> getObservers() {
- return ((ChainingMetadataProvider) internalProvider).getObservers();
- }
-
/**
* Get the URL to metadata for a specific entityID.
*
@@ -384,13 +340,13 @@ public abstract class AbstractChainingMetadataProvider extends SimpleMetadataPro
* Creates a new implementation specific SAML2 metadata provider.
*
* @param entityId EntityId
- * @return MetadataProvider
+ * @return MetadataResolver
* @throws EaafConfigurationException In case of an error
* @throws IOException In case of an error
* @throws CertificateException In case of an error
* @throws ConfigurationException In case of an error
*/
- protected abstract MetadataProvider createNewMetadataProvider(String entityId)
+ protected abstract MetadataResolver createNewMetadataProvider(String entityId)
throws EaafConfigurationException, IOException, CertificateException;
/**
@@ -398,33 +354,25 @@ public abstract class AbstractChainingMetadataProvider extends SimpleMetadataPro
*
* @throws EaafConfigurationException In case of an error
*/
+ @Nonnull
protected abstract List<String> getAllMetadataUrlsFromConfiguration()
throws EaafConfigurationException;
- protected void emitChangeEvent() {
- if (getObservers() == null || getObservers().size() == 0) {
- return;
- }
-
- final List<Observer> tempObserverList = new ArrayList<>(getObservers());
- for (final ObservableMetadataProvider.Observer observer : tempObserverList) {
- if (observer != null) {
- observer.onEvent(this);
- }
- }
- }
- private Map<String, HTTPMetadataProvider> getAllActuallyLoadedProviders() {
- final Map<String, HTTPMetadataProvider> loadedproviders =
+ private Map<String, MetadataResolver> getAllActuallyLoadedResolvers() {
+ final Map<String, MetadataResolver> loadedproviders =
new HashMap<>();
- final ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider;
// make a Map of all actually loaded HTTPMetadataProvider
- final List<MetadataProvider> providers = chainProvider.getProviders();
- for (final MetadataProvider provider : providers) {
- if (provider instanceof HTTPMetadataProvider) {
- final HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider;
- loadedproviders.put(httpprovider.getMetadataURI(), httpprovider);
+ 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);
}
}
@@ -433,19 +381,17 @@ public abstract class AbstractChainingMetadataProvider extends SimpleMetadataPro
}
private void addAndRemoveMetadataProvider() throws EaafConfigurationException {
- if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) {
- log.info("Reload MOAMetaDataProvider.");
+ 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<String, MetadataProvider> providersinuse = new HashMap<>();
- final ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider;
+ final Map<String, MetadataResolver> providersinuse = new HashMap<>();
// get all actually loaded metadata providers
- final Map<String, HTTPMetadataProvider> loadedproviders = getAllActuallyLoadedProviders();
+ final Map<String, MetadataResolver> loadedproviders = getAllActuallyLoadedResolvers();
/*
* TODO: maybe add metadata provider destroy after timeout. But could be a
@@ -460,7 +406,6 @@ public abstract class AbstractChainingMetadataProvider extends SimpleMetadataPro
// compare actually loaded Providers with configured SAML2 SPs
final List<String> allMetadataUrls = getAllMetadataUrlsFromConfiguration();
- if (allMetadataUrls != null) {
final Iterator<String> metadataUrlInterator = allMetadataUrls.iterator();
while (metadataUrlInterator.hasNext()) {
final String metadataurl = metadataUrlInterator.next();
@@ -477,15 +422,15 @@ public abstract class AbstractChainingMetadataProvider extends SimpleMetadataPro
}
}
- }
+
// remove all actually loaded MetadataProviders with are not in ConfigurationDB
// any more
- final Collection<HTTPMetadataProvider> notusedproviders = loadedproviders.values();
- for (final HTTPMetadataProvider provider : notusedproviders) {
- final String metadataurl = provider.getMetadataURI();
- try {
- provider.destroy();
+ final Collection<MetadataResolver> 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
@@ -493,31 +438,43 @@ public abstract class AbstractChainingMetadataProvider extends SimpleMetadataPro
* unmodifiableList to hold all registrated MetadataProviders.
*/
// chainProvider.removeMetadataProvider(provider);
- log.info("Remove not used MetadataProvider with MetadataURL " + metadataurl);
- } catch (final Throwable e) {
- log.error("HTTPMetadataProvider with URL " + metadataurl
- + " can not be removed from the list of actually loaded Providers.", e);
-
- }
}
+ }
+
+ private EntityDescriptor resolveEntityDescripor(String entityId) throws ResolverException {
+ final CriteriaSet criteria = new CriteriaSet();
+ criteria.add(new EntityIdCriterion(entityId));
+ for (final MetadataResolver resolver : internalResolvers) {
try {
- chainProvider.setProviders(new ArrayList<>(providersinuse.values()));
- emitChangeEvent();
+ final EntityDescriptor descriptors = resolver.resolveSingle(criteria);
+ if (descriptors != null) {
+ return descriptors;
+ }
- } catch (final MetadataProviderException e) {
- log.warn(
- "ReInitalize AbstractMetaDataProvider is not possible! Service has to be restarted manualy",
- e);
+ } catch (final ResolverException e) {
+ continue;
}
- } else {
- log.warn(
- "ReInitalize AbstractMetaDataProvider is not possible! Service has to be restarted manualy");
}
+ return null;
+
+ }
+
+ private void destroyMetadataResolver(MetadataResolver resolver) {
+ if (resolver instanceof AbstractMetadataResolver) {
+ final AbstractMetadataResolver httpprovider = (AbstractMetadataResolver) resolver;
+ log.debug("Destroy metadata resolver with id: {}", httpprovider.getId());
+ httpprovider.destroy();
+
+ } else {
+ log.warn("Metadata resolver: {} can not be destroyed. Reason: unsupported type: {}",
+ resolver.getId(), resolver.getClass().getName());
+
+ }
}
}