summaryrefslogtreecommitdiff
path: root/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2020-02-04 17:37:34 +0100
committerThomas Lenz <thomas.lenz@egiz.gv.at>2020-02-04 17:37:34 +0100
commite7610325ee2f1d1f4e97e1e7a9b212e692836b5a (patch)
treeed7c0dba5fed47e80e68b4ab5a63846c5724a8e7 /eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata
parent41ea2fdf782cd64d7d29f73c2e83f9c255810818 (diff)
downloadEAAF-Components-e7610325ee2f1d1f4e97e1e7a9b212e692836b5a.tar.gz
EAAF-Components-e7610325ee2f1d1f4e97e1e7a9b212e692836b5a.tar.bz2
EAAF-Components-e7610325ee2f1d1f4e97e1e7a9b212e692836b5a.zip
first stable version that uses OpenSAML 3.x
Diffstat (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata')
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java334
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverAdapter.java39
-rw-r--r--eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverFactory.java293
3 files changed, 339 insertions, 327 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 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<MetadataResolver> internalResolvers;
+
+ @Nonnull
+ @NonnullElements
+ private final List<MetadataResolver> 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<EntityDescriptor> resolve(@Nullable final CriteriaSet criteria) throws ResolverException {
- for (final MetadataResolver resolver : internalResolvers) {
- try {
- final Iterable<EntityDescriptor> descriptors = resolver.resolve(criteria);
- if (descriptors != null && descriptors.iterator().hasNext()) {
- return descriptors;
-
- }
-
- } catch (final ResolverException e) {
- continue;
-
- }
+ @Nonnull
+ public final Iterable<EntityDescriptor> resolve(@Nullable final CriteriaSet criteria)
+ throws ResolverException {
+ for (final MetadataResolver resolver : internalResolvers) {
+ try {
+ final Iterable<EntityDescriptor> 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<String> 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<String, MetadataResolver> getAllActuallyLoadedResolvers() {
final Map<String, MetadataResolver> 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<String, MetadataResolver> providersinuse = new HashMap<>();
+
+ // get all actually loaded metadata providers
+ final Map<String, MetadataResolver> 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<String> allMetadataUrls = getAllMetadataUrlsFromConfiguration();
+
+ final Iterator<String> 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<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
* (UnsupportedOperationException) The ChainingMetadataProvider use internal a
* unmodifiableList to hold all registrated MetadataProviders.
*/
- final Map<String, MetadataResolver> providersinuse = new HashMap<>();
+ // chainProvider.removeMetadataProvider(provider);
- // get all actually loaded metadata providers
- final Map<String, MetadataResolver> 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<String> allMetadataUrls = getAllMetadataUrlsFromConfiguration();
-
- final Iterator<String> 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<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
- * (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();
-
+
}
-
+
}
diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverAdapter.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverAdapter.java
index bd2b79cb..d2b861dc 100644
--- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverAdapter.java
+++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/PvpMetadataResolverAdapter.java
@@ -1,18 +1,22 @@
package at.gv.egiz.eaaf.modules.pvp2.impl.metadata;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider;
+
import org.joda.time.DateTime;
import org.opensaml.core.criterion.EntityIdCriterion;
import org.opensaml.saml.metadata.resolver.ExtendedRefreshableMetadataResolver;
import org.opensaml.saml.metadata.resolver.filter.MetadataFilter;
import org.opensaml.saml.saml2.metadata.EntityDescriptor;
-import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvp2MetadataProvider;
+import lombok.extern.slf4j.Slf4j;
import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
import net.shibboleth.utilities.java.support.resolver.ResolverException;
-public class PvpMetadataResolverAdapter implements IPvp2MetadataProvider {
-
- private ExtendedRefreshableMetadataResolver internalProvider;
+@Slf4j
+public class PvpMetadataResolverAdapter implements IPvp2MetadataProvider, IRefreshableMetadataProvider {
+
+ private final ExtendedRefreshableMetadataResolver internalProvider;
public PvpMetadataResolverAdapter(ExtendedRefreshableMetadataResolver provider) {
this.internalProvider = provider;
@@ -27,7 +31,7 @@ public class PvpMetadataResolverAdapter implements IPvp2MetadataProvider {
@Override
public DateTime getLastRefresh() {
return internalProvider.getLastRefresh();
-
+
}
@Override
@@ -38,7 +42,7 @@ public class PvpMetadataResolverAdapter implements IPvp2MetadataProvider {
@Override
public boolean isRequireValidMetadata() {
return internalProvider.isRequireValidMetadata();
-
+
}
@Override
@@ -50,12 +54,12 @@ public class PvpMetadataResolverAdapter implements IPvp2MetadataProvider {
@Override
public MetadataFilter getMetadataFilter() {
return internalProvider.getMetadataFilter();
-
+
}
@Override
public void setMetadataFilter(MetadataFilter newFilter) {
- internalProvider.setMetadataFilter(newFilter);
+ internalProvider.setMetadataFilter(newFilter);
}
@@ -67,7 +71,7 @@ public class PvpMetadataResolverAdapter implements IPvp2MetadataProvider {
@Override
public EntityDescriptor resolveSingle(CriteriaSet criteria) throws ResolverException {
return internalProvider.resolveSingle(criteria);
-
+
}
@Override
@@ -80,7 +84,7 @@ public class PvpMetadataResolverAdapter implements IPvp2MetadataProvider {
final CriteriaSet criteria = new CriteriaSet();
criteria.add(new EntityIdCriterion(entityId));
return internalProvider.resolveSingle(criteria);
-
+
}
@Override
@@ -93,4 +97,19 @@ public class PvpMetadataResolverAdapter implements IPvp2MetadataProvider {
return internalProvider.wasLastRefreshSuccess();
}
+ @Override
+ public boolean refreshMetadataProvider(String entityID) {
+ try {
+ log.trace("Refeshing metadata-provider: {} ... ", getId());
+ internalProvider.refresh();
+ return true;
+
+ } catch (final ResolverException e) {
+ log.warn("Refreshing of metadata-provider: {} failed. Reason: {}",
+ getId(), e.getMessage());
+ return false;
+
+ }
+ }
+
}
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
index f548bc7b..0b505e56 100644
--- 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
@@ -8,23 +8,31 @@ import javax.annotation.Nullable;
import javax.annotation.PostConstruct;
import javax.net.ssl.SSLHandshakeException;
+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.Pvp2MetadataException;
+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 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.AbstractReloadingMetadataResolver;
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 com.google.common.base.Predicates;
+import com.google.common.base.Throwables;
+import com.google.common.collect.FluentIterable;
import lombok.extern.slf4j.Slf4j;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
import net.shibboleth.utilities.java.support.resource.Resource;
import net.shibboleth.utilities.java.support.xml.ParserPool;
@@ -34,13 +42,18 @@ public class PvpMetadataResolverFactory implements IDestroyableObject {
private static final String URI_PREFIX_HTTP = "http:";
private static final String URI_PREFIX_HTTPS = "https:";
+ private static final String NOT_SUCCESS = "Maybe metadata was expired";
+
private Timer timer = null;
-
- @Autowired private IConfiguration authConfig;
- @Autowired private ResourceLoader resourceLoader;
-
+
+ @Autowired
+ private IConfiguration authConfig;
+ @Autowired
+ private ResourceLoader resourceLoader;
+
/**
- * Create a single SAML2 metadata provider by using the default OpenSAML3 parser-pool.
+ * 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
@@ -54,17 +67,18 @@ public class PvpMetadataResolverFactory implements IDestroyableObject {
*
* @return SAML2 Metadata Provider, or null if the metadata provider can not
* initialized
+ * @throws Pvp2MetadataException In case of an initialization error
*/
- @Nullable
+ @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);
-
+ @Nullable final HttpClient httpClient) throws Pvp2MetadataException {
+ return createMetadataProvider(metadataLocation, filter, idForLogging,
+ XMLObjectProviderRegistrySupport.getParserPool(),
+ httpClient);
+
}
-
+
/**
* Create a single SAML2 metadata provider.
*
@@ -80,57 +94,74 @@ public class PvpMetadataResolverFactory implements IDestroyableObject {
*
* @return SAML2 Metadata Provider, or null if the metadata provider can not
* initialized
+ * @throws Pvp2MetadataException In case of an initialization error
*/
- @Nullable
+ @Nullable
public IPvp2MetadataProvider createMetadataProvider(@Nonnull final String metadataLocation,
@Nullable final MetadataFilter filter, @Nonnull final String idForLogging,
- @Nullable final ParserPool pool, @Nullable final HttpClient httpClient) {
-
+ @Nullable final ParserPool pool, @Nullable final HttpClient httpClient) throws Pvp2MetadataException {
+
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);
+
+ try {
+ if (metadataLocation.startsWith(URI_PREFIX_HTTP)
+ || metadataLocation.startsWith(URI_PREFIX_HTTPS)) {
+ internalProvider = createNewHttpMetaDataProvider(metadataLocation, filter,
+ idForLogging, timer, pool, httpClient);
+
} else {
- log.warn("Can not load http(s) based SAML2 metadata without a HTTP client");
-
+ final String absoluteMetadataLocation =
+ FileUtils.makeAbsoluteUrl(metadataLocation, authConfig.getConfigurationRootDirectory());
+ final 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: {} not found or not exist", absoluteMetadataLocation);
+ throw new Pvp2MetadataException("internal.pvp.05",
+ new Object[] { absoluteMetadataLocation, "File NOT found or exist." });
+
+ }
}
- } else {
- String absoluteMetadataLocation;
- try {
- absoluteMetadataLocation =
- FileUtils.makeAbsoluteUrl(metadataLocation, authConfig.getConfigurationRootDirectory());
+ } catch (final ComponentInitializationException e) {
+ log.warn("Failed to load Metadata file for {} [ {} ]",
+ idForLogging, e.getMessage());
+ checkResolverInitializationError(e, metadataLocation);
- 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 Exception e) {
+ throw new Pvp2MetadataException("internal.pvp.09", new Object[] { metadataLocation, e.getMessage() });
+ }
- } catch (final IOException e) {
- log.warn("SAML2 metadata URL is invalid: " + metadataLocation, e);
+ if (!internalProvider.wasLastRefreshSuccess()) {
+ log.info("Metadata loading from source: {} failed. {}", metadataLocation, NOT_SUCCESS);
+ throw new Pvp2MetadataException("internal.pvp.09", new Object[] { metadataLocation, NOT_SUCCESS });
- }
}
- if (internalProvider != null) {
- return new PvpMetadataResolverAdapter(internalProvider);
-
- } else {
- log.warn("SAML2 metadata has an unsupported metadata location prefix: " + metadataLocation);
- return null;
-
+ return new PvpMetadataResolverAdapter(internalProvider);
+
+ }
+
+ @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");
}
@@ -142,55 +173,26 @@ public class PvpMetadataResolverFactory implements IDestroyableObject {
* @param idForLogging Id, which is used for Logging
* @param timer {@link Timer} which is used to schedule metadata refresh
* operations
- * @param pool
+ * @param pool SAML2 parser pool that should be used
*
* @return SAML2 Metadata Provider
- * @throws IOException
+ * @throws IOException In case of a metadata resource error
+ * @throws ComponentInitializationException In case of a metadata resolver
+ * initialization error
*/
private ExtendedRefreshableMetadataResolver createNewFileSystemMetaDataProvider(final Resource metadataFile,
final MetadataFilter filter, final String idForLogging, final Timer timer,
- final ParserPool pool) throws IOException {
+ final ParserPool pool) throws IOException, ComponentInitializationException {
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);
+ fileSystemResolver = new ResourceBackedMetadataResolver(timer, metadataFile);
+ injectMetadataResolverConfiguration(fileSystemResolver, filter, pool);
+ fileSystemResolver.setId(metadataFile.getURI().toASCIIString());
+ fileSystemResolver.initialize();
- if (fileSystemResolver != null) {
- fileSystemResolver.destroy();
+ log.trace("Set-up metadata-resolver with ID: {} as: {}",
+ idForLogging, fileSystemResolver.getClass().getSimpleName());
- }
-
- }
-
- return null;
+ return fileSystemResolver;
}
@@ -202,70 +204,75 @@ public class PvpMetadataResolverFactory implements IDestroyableObject {
* @param idForLogging Id, which is used for Logging
* @param timer {@link Timer} which is used to schedule metadata refresh
* operations
- * @param pool
- *
+ * @param pool SAML2 parser pool that should be used
* @return SAML2 Metadata Provider
+ * @throws ComponentInitializationException In case of a metadata resolver
+ * initialization error
+ * @throws ResolverException In case of an internal OpenSAML
+ * resolver error
*/
private ExtendedRefreshableMetadataResolver createNewHttpMetaDataProvider(final String metadataUrl,
final MetadataFilter filter, final String idForLogging, final Timer timer,
- final ParserPool pool, final HttpClient httpClient) {
+ final ParserPool pool, final HttpClient httpClient) throws ComponentInitializationException,
+ ResolverException {
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 = new HTTPMetadataResolver(timer, httpClient, metadataUrl);
+ injectMetadataResolverConfiguration(httpMetadataResolver, filter, pool);
+ httpMetadataResolver.setId(metadataUrl);
+ httpMetadataResolver.initialize();
- httpMetadataResolver.setMetadataFilter(filter);
- httpMetadataResolver.setId(metadataUrl);
- httpMetadataResolver.initialize();
+ log.trace("Set-up metadata-resolver with ID: {} as: {}",
+ idForLogging, httpMetadataResolver.getClass().getSimpleName());
- httpMetadataResolver.setRequireValidMetadata(true);
+ return httpMetadataResolver;
- 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);
+ private void injectMetadataResolverConfiguration(AbstractReloadingMetadataResolver resolver,
+ final MetadataFilter filter, final ParserPool pool) {
+ if (pool != null) {
+ resolver.setParserPool(pool);
- }
- if (e.getCause() != null && e.getCause().getCause() instanceof SignatureValidationException) {
- log.warn("Signature verification for metadata" + metadataUrl + " FAILED.", e);
+ } else {
+ resolver.setParserPool(
+ XMLObjectProviderRegistrySupport.getParserPool());
- }
- if (e.getCause() != null && e.getCause().getCause() instanceof SchemaValidationException) {
- log.warn("Schema validation for metadata " + metadataUrl + " FAILED.", e);
- }
+ }
+
+ resolver.setRequireValidMetadata(true);
+ resolver.setMinRefreshDelay(1000 * 60 * 15); // 15 minutes
+ resolver.setMaxRefreshDelay(1000 * 60 * 60 * 24); // 24 hours
+ resolver.setMetadataFilter(filter);
+
+ }
- log.warn("Failed to load Metadata file for " + idForLogging + "[ " + e.getMessage() + " ]",
+ private void checkResolverInitializationError(ComponentInitializationException e, String metadataLocation)
+ throws Pvp2MetadataException {
+ if (FluentIterable.from(Throwables.getCausalChain(e)).filter(
+ Predicates.instanceOf(SSLHandshakeException.class)).first().isPresent()) {
+ log.info("SSL-Server certificate for metadata: {} not trusted.", metadataLocation, null, e);
+ throw new Pvp2MetadataException("internal.pvp.06", new Object[] { metadataLocation, e.getMessage() },
e);
- if (httpMetadataResolver != null) {
- log.debug("Destroy failed Metadata provider");
- httpMetadataResolver.destroy();
+ } else if (FluentIterable.from(Throwables.getCausalChain(e)).filter(
+ Predicates.instanceOf(SignatureValidationException.class)).first().isPresent()) {
+ log.info("Signature verification for metadata: {} FAILED.", metadataLocation, null, e);
+ throw new Pvp2MetadataException("internal.pvp.07", new Object[] { metadataLocation, e.getMessage() },
+ e);
- }
+ } else if (FluentIterable.from(Throwables.getCausalChain(e)).filter(
+ Predicates.instanceOf(SchemaValidationException.class)).first().isPresent()) {
+ log.info("Schema validation for metadata: {} FAILED.", metadataLocation, null, e);
+ throw new Pvp2MetadataException("internal.pvp.08", new Object[] { metadataLocation, e.getMessage() },
+ e);
+
+ } else {
+ log.info("Generic initialization error for metadata: {}", metadataLocation, null, e);
+ throw new Pvp2MetadataException("internal.pvp.09", new Object[] { metadataLocation, e.getMessage() },
+ e);
}
- 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");
-
- }
-
}