aboutsummaryrefslogtreecommitdiff
path: root/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java')
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java303
1 files changed, 272 insertions, 31 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java
index 99567478d..6d9022bd9 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java
@@ -1,20 +1,43 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ *******************************************************************************/
package at.gv.egovernment.moa.id.protocols.pvp2x.metadata;
-import java.io.File;
-import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Timer;
import javax.xml.namespace.QName;
import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.protocol.Protocol;
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.FilesystemMetadataProvider;
import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider;
import org.opensaml.saml2.metadata.provider.MetadataFilter;
import org.opensaml.saml2.metadata.provider.MetadataProvider;
@@ -22,22 +45,20 @@ import org.opensaml.saml2.metadata.provider.MetadataProviderException;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.parse.BasicParserPool;
-import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWSecureSocketFactory;
import at.gv.egovernment.moa.id.commons.db.ConfigurationDBRead;
-import at.gv.egovernment.moa.id.commons.db.ConfigurationDBUtils;
import at.gv.egovernment.moa.id.commons.db.dao.config.OAPVP2;
import at.gv.egovernment.moa.id.commons.db.dao.config.OnlineApplication;
-import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
import at.gv.egovernment.moa.id.protocols.pvp2x.verification.MetadataSignatureFilter;
-import at.gv.egovernment.moa.id.util.SSLUtils;
import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
public class MOAMetadataProvider implements MetadataProvider {
private static MOAMetadataProvider instance = null;
private static Object mutex = new Object();
-
+ private static Date timestamp = null;
+
public static MOAMetadataProvider getInstance() {
if (instance == null) {
synchronized (mutex) {
@@ -49,43 +70,201 @@ public class MOAMetadataProvider implements MetadataProvider {
return instance;
}
+ public static Date getTimeStamp() {
+ return timestamp;
+ }
+
+ public static void reInitialize() {
+ synchronized (mutex) {
+
+ /**add new Metadataprovider or remove Metadataprovider which are not in use any more.**/
+ if (instance != null)
+ instance.addAndRemoveMetadataProvider();
+
+ else
+ Logger.info("MOAMetadataProvider is not loaded.");
+ }
+ }
+
+ public static void destroy() {
+ if (instance != null) {
+ instance.internalDestroy();
+
+ } else {
+ Logger.info("MOAMetadataProvider is not loaded. Accordingly it can not be destroyed");
+ }
+ }
+
MetadataProvider internalProvider;
+
+ private void addAndRemoveMetadataProvider() {
+ if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) {
+ Logger.info("Relaod MOAMetaDataProvider.");
+
+ /*OpenSAML ChainingMetadataProvider can not remove a MetadataProvider (UnsupportedOperationException)
+ *The ChainingMetadataProvider use internal a unmodifiableList to hold all registrated MetadataProviders.*/
+ Map<String, MetadataProvider> providersinuse = new HashMap<String, MetadataProvider>();
+
+ Map<String, HTTPMetadataProvider> loadedproviders = new HashMap<String, HTTPMetadataProvider>();
+ ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider;
+
+ //make a Map of all actually loaded HTTPMetadataProvider
+ List<MetadataProvider> providers = chainProvider.getProviders();
+ for (MetadataProvider provider : providers) {
+ if (provider instanceof HTTPMetadataProvider) {
+ HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider;
+ loadedproviders.put(httpprovider.getMetadataURI(), httpprovider);
+ }
+ }
+
+ //load all PVP2 OAs form ConfigurationDatabase and
+ //compare actually loaded Providers with configured PVP2 OAs
+ List<OnlineApplication> oaList = ConfigurationDBRead
+ .getAllActiveOnlineApplications();
+
+ //set Timestamp
+ timestamp = new Date();
+
+ Iterator<OnlineApplication> oaIt = oaList.iterator();
+ while (oaIt.hasNext()) {
+ HTTPMetadataProvider httpProvider = null;
+
+ try {
+ OnlineApplication oa = oaIt.next();
+ OAPVP2 pvp2Config = oa.getAuthComponentOA().getOAPVP2();
+ if (pvp2Config != null && MiscUtil.isNotEmpty(pvp2Config.getMetadataURL())) {
+
+ String metadataurl = pvp2Config.getMetadataURL();
+
+ if (loadedproviders.containsKey(metadataurl)) {
+ //PVP2 OA is actually loaded, to nothing
+ providersinuse.put(metadataurl, loadedproviders.get(metadataurl));
+ loadedproviders.remove(metadataurl);
+
+
+ } else if ( MiscUtil.isNotEmpty(metadataurl) &&
+ !providersinuse.containsKey(metadataurl) ) {
+ //PVP2 OA is new, add it to MOAMetadataProvider
+ Logger.info("Loading metadata for: " + oa.getFriendlyName());
+ httpProvider = createNewHTTPMetaDataProvider(
+ pvp2Config.getMetadataURL(),
+ pvp2Config.getCertificate(),
+ oa.getFriendlyName());
+
+ if (httpProvider != null)
+ providersinuse.put(metadataurl, httpProvider);
+
+ }
+ }
+ } catch (Throwable e) {
+ Logger.error(
+ "Failed to add Metadata (unhandled reason: "
+ + e.getMessage(), e);
+
+ if (httpProvider != null) {
+ Logger.debug("Destroy failed Metadata provider");
+ httpProvider.destroy();
+ }
+
+ }
+ }
+
+ //remove all actually loaded MetadataProviders with are not in ConfigurationDB any more
+ Collection<HTTPMetadataProvider> notusedproviders = loadedproviders.values();
+ for (HTTPMetadataProvider provider : notusedproviders) {
+ String metadataurl = provider.getMetadataURI();
+
+ try {
+
+ provider.destroy();
+
+ /*OpenSAML ChainingMetadataProvider can not remove a MetadataProvider (UnsupportedOperationException)
+ *The ChainingMetadataProvider use internal a unmodifiableList to hold all registrated MetadataProviders.*/
+ //chainProvider.removeMetadataProvider(provider);
+
+ Logger.info("Remove not used MetadataProvider with MetadataURL " + metadataurl);
+
+ } catch (Throwable e) {
+ Logger.error("HTTPMetadataProvider with URL " + metadataurl
+ + " can not be removed from the list of actually loaded Providers.", e);
+
+ }
+
+ }
+
+ try {
+ chainProvider.setProviders(new ArrayList<MetadataProvider>(providersinuse.values()));
+
+ } catch (MetadataProviderException e) {
+ Logger.warn("ReInitalize MOAMetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy", e);
+
+ }
+
+
+
+ } else {
+ Logger.warn("ReInitalize MOAMetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy");
+ }
+
+ }
+
+
+ public void internalDestroy() {
+ if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) {
+ Logger.info("Destrorying MOAMetaDataProvider.");
+ ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider;
+
+ List<MetadataProvider> providers = chainProvider.getProviders();
+ for (MetadataProvider provider : providers) {
+ if (provider instanceof HTTPMetadataProvider) {
+ HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider;
+ Logger.debug("Destroy HTTPMetadataProvider +" + httpprovider.getMetadataURI());
+ httpprovider.destroy();
+
+ } else {
+ Logger.warn("MetadataProvider can not be destroyed.");
+ }
+ }
+ instance = null;
+ } else {
+ Logger.warn("ReInitalize MOAMetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy");
+ }
+ }
+
private MOAMetadataProvider() {
ChainingMetadataProvider chainProvider = new ChainingMetadataProvider();
Logger.info("Loading metadata");
+
+ Map<String, MetadataProvider> providersinuse = new HashMap<String, MetadataProvider>();
+
List<OnlineApplication> oaList = ConfigurationDBRead
.getAllActiveOnlineApplications();
Iterator<OnlineApplication> oaIt = oaList.iterator();
while (oaIt.hasNext()) {
+ HTTPMetadataProvider httpProvider = null;
+
try {
OnlineApplication oa = oaIt.next();
Logger.info("Loading metadata for: " + oa.getFriendlyName());
OAPVP2 pvp2Config = oa.getAuthComponentOA().getOAPVP2();
- if (pvp2Config != null) {
+ if (pvp2Config != null && MiscUtil.isNotEmpty(pvp2Config.getMetadataURL())) {
String metadataURL = pvp2Config.getMetadataURL();
- try {
- // TODO: use proper SSL checking
- HTTPMetadataProvider httpProvider = new HTTPMetadataProvider(
- metadataURL, 20000);
- httpProvider.setParserPool(new BasicParserPool());
- httpProvider.setRequireValidMetadata(true);
- MetadataFilter filter = new MetadataSignatureFilter(
- metadataURL, pvp2Config.getCertificate());
- httpProvider.setMetadataFilter(filter);
- chainProvider.addMetadataProvider(httpProvider);
- httpProvider.initialize();
- } catch (MetadataProviderException e) {
- Logger.error(
- "Failed to add Metadata file for "
- + oa.getFriendlyName() + "[ "
- + e.getMessage() + " ]", e);
- } catch (CertificateException e) {
- Logger.error(
- "Failed to add Metadata file for "
- + oa.getFriendlyName() + "[ "
- + e.getMessage() + " ]", e);
+
+ if (!providersinuse.containsKey(metadataURL)) {
+
+ httpProvider = createNewHTTPMetaDataProvider(
+ metadataURL,
+ pvp2Config.getCertificate(),
+ oa.getFriendlyName());
+
+ if (httpProvider != null)
+ providersinuse.put(metadataURL, httpProvider);
+
+ } else {
+ Logger.info(metadataURL + " are already added.");
}
+
} else {
Logger.info(oa.getFriendlyName()
+ " is not a PVP2 Application skipping");
@@ -94,12 +273,74 @@ public class MOAMetadataProvider implements MetadataProvider {
Logger.error(
"Failed to add Metadata (unhandled reason: "
+ e.getMessage(), e);
+
+ if (httpProvider != null) {
+ Logger.debug("Destroy failed Metadata provider");
+ httpProvider.destroy();
+ }
}
}
+
+ try {
+ chainProvider.setProviders(new ArrayList<MetadataProvider>(providersinuse.values()));
+
+ } catch (MetadataProviderException e) {
+ Logger.error(
+ "Failed to add Metadata (unhandled reason: "
+ + e.getMessage(), e);
+ }
+
internalProvider = chainProvider;
+ timestamp = new Date();
}
+
+ private HTTPMetadataProvider createNewHTTPMetaDataProvider(String metadataURL, byte[] certificate, String oaName) {
+ HTTPMetadataProvider httpProvider = null;
+ Timer timer= null;
+
+ try {
+ timer = new Timer();
+ httpProvider = new HTTPMetadataProvider(timer, new HttpClient(),
+ metadataURL);
+ httpProvider.setParserPool(new BasicParserPool());
+ httpProvider.setRequireValidMetadata(true);
+ httpProvider.setMinRefreshDelay(1000*60*15); //15 minutes
+ httpProvider.setMaxRefreshDelay(1000*60*60*24); //24 hours
+ //httpProvider.setRefreshDelayFactor(0.1F);
+
+ // TODO: use proper SSL checking
+
+ MetadataFilter filter = new MetadataSignatureFilter(
+ metadataURL, certificate);
+ httpProvider.setMetadataFilter(filter);
+ httpProvider.initialize();
+
+ return httpProvider;
+
+
+ } catch (Throwable e) {
+ Logger.error(
+ "Failed to add Metadata file for "
+ + oaName + "[ "
+ + e.getMessage() + " ]", e);
+
+ if (httpProvider != null) {
+ Logger.debug("Destroy failed Metadata provider");
+ httpProvider.destroy();
+ }
+
+ if (timer != null) {
+ Logger.debug("Destroy Timer.");
+ timer.cancel();
+ }
+
+ }
+
+ return null;
+ }
+
public boolean requireValidMetadata() {
return internalProvider.requireValidMetadata();
}