From 91d38d59b42ee77346b0d33315f403d8fa678576 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Mon, 17 Jul 2017 10:25:02 +0200 Subject: update MOA SAML2 metadata provider to support metadata located on file system --- .../pvp2x/metadata/MOAMetadataProvider.java | 145 ++++++++++----------- .../pvp2x/metadata/SimpleMOAMetadataProvider.java | 116 ++++++++++++++++- 2 files changed, 182 insertions(+), 79 deletions(-) (limited to 'id/server/idserverlib/src/main/java/at/gv') 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 b2597c3cb..5380d7f53 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 @@ -38,6 +38,7 @@ import javax.xml.namespace.QName; import org.opensaml.saml2.metadata.EntitiesDescriptor; import org.opensaml.saml2.metadata.EntityDescriptor; import org.opensaml.saml2.metadata.RoleDescriptor; +import org.opensaml.saml2.metadata.provider.BaseMetadataProvider; import org.opensaml.saml2.metadata.provider.ChainingMetadataProvider; import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider; import org.opensaml.saml2.metadata.provider.MetadataFilter; @@ -45,6 +46,7 @@ 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.opensaml.xml.parse.BasicParserPool; import org.springframework.stereotype.Service; import at.gv.egovernment.moa.id.auth.IDestroyableObject; @@ -52,7 +54,6 @@ import at.gv.egovernment.moa.id.auth.IGarbageCollectorProcessing; import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.commons.config.MOAIDConfigurationConstants; -import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.InterfederatedIDPPublicServiceFilter; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.PVPMetadataFilterChain; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.SchemaValidationFilter; @@ -154,7 +155,7 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider //reload metadata provider IOAAuthParameters oaParam = - AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(entityID); + authConfig.getOnlineApplicationParameter(entityID); if (oaParam != null) { String metadataURL = oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_PVP2X_URL); if (MiscUtil.isNotEmpty(metadataURL)) { @@ -178,10 +179,11 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider timer = new Timer(true); ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; - HTTPMetadataProvider newMetadataProvider = createNewHTTPMetaDataProvider(metadataURL, + MetadataProvider newMetadataProvider = createNewMoaMetadataProvider(metadataURL, buildMetadataFilterChain(oaParam, metadataURL, cert), oaFriendlyName, - timer); + timer, + new BasicParserPool()); chainProvider.addMetadataProvider(newMetadataProvider); @@ -203,9 +205,6 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider Logger.debug("Can not refresh PVP2X metadata: NO onlineApplication with Id: " + entityID); - } catch (ConfigurationException e) { - Logger.warn("Access MOA-ID configuration FAILED.", e); - } catch (MetadataProviderException e) { Logger.warn("Refresh PVP2X metadata for onlineApplication: " + entityID + " FAILED.", e); @@ -268,7 +267,7 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider //load all PVP2 OAs form ConfigurationDatabase and //compare actually loaded Providers with configured PVP2 OAs - Map allOAs = AuthConfigurationProviderFactory.getInstance().getConfigurationWithWildCard( + Map allOAs = authConfig.getConfigurationWithWildCard( MOAIDConfigurationConstants.PREFIX_MOAID_SERVICES + ".%." + MOAIDConfigurationConstants.SERVICE_UNIQUEIDENTIFIER); @@ -279,7 +278,7 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider Entry oaKeyPair = oaInterator.next(); IOAAuthParameters oaParam = - AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(oaKeyPair.getValue()); + authConfig.getOnlineApplicationParameter(oaKeyPair.getValue()); if (oaParam != null) { String metadataurl = oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_PVP2X_URL); @@ -409,83 +408,79 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider ChainingMetadataProvider chainProvider = new ChainingMetadataProvider(); Logger.info("Loading metadata"); Map providersinuse = new HashMap(); - try { - Map allOAs = AuthConfigurationProviderFactory.getInstance().getConfigurationWithWildCard( - MOAIDConfigurationConstants.PREFIX_MOAID_SERVICES - + ".%." - + MOAIDConfigurationConstants.SERVICE_UNIQUEIDENTIFIER); - - if (allOAs != null) { - Iterator> oaInterator = allOAs.entrySet().iterator(); - while (oaInterator.hasNext()) { - Entry oaKeyPair = oaInterator.next(); - - IOAAuthParameters oaParam = - AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(oaKeyPair.getValue()); - if (oaParam != null) { - String metadataurl = oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_PVP2X_URL); - String oaFriendlyName = oaParam.getFriendlyName(); - HTTPMetadataProvider httpProvider = null; + Map allOAs = authConfig.getConfigurationWithWildCard( + MOAIDConfigurationConstants.PREFIX_MOAID_SERVICES + + ".%." + + MOAIDConfigurationConstants.SERVICE_UNIQUEIDENTIFIER); + + if (allOAs != null) { + Iterator> oaInterator = allOAs.entrySet().iterator(); + while (oaInterator.hasNext()) { + Entry oaKeyPair = oaInterator.next(); - try { - String certBase64 = oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_PVP2X_CERTIFICATE); - if (MiscUtil.isNotEmpty(certBase64) && MiscUtil.isNotEmpty(metadataurl)) { - byte[] cert = Base64Utils.decode(certBase64, false); - - - if (timer == null) - timer = new Timer(true); - - Logger.info("Loading metadata for: " + oaFriendlyName); - if (!providersinuse.containsKey(metadataurl)) { - httpProvider = createNewHTTPMetaDataProvider( - metadataurl, - buildMetadataFilterChain(oaParam, metadataurl, cert), - oaFriendlyName, - timer); - - if (httpProvider != null) - providersinuse.put(metadataurl, httpProvider); + IOAAuthParameters oaParam = + authConfig.getOnlineApplicationParameter(oaKeyPair.getValue()); + if (oaParam != null) { + String metadataurl = oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_PVP2X_URL); + String oaFriendlyName = oaParam.getFriendlyName(); + MetadataProvider httpProvider = null; + + try { + String certBase64 = oaParam.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_PROTOCOLS_PVP2X_CERTIFICATE); + if (MiscUtil.isNotEmpty(certBase64) && MiscUtil.isNotEmpty(metadataurl)) { + byte[] cert = Base64Utils.decode(certBase64, false); - } else { - Logger.info(metadataurl + " are already added."); - } + + if (timer == null) + timer = new Timer(true); + + Logger.info("Loading metadata for: " + oaFriendlyName); + if (!providersinuse.containsKey(metadataurl)) { + httpProvider = createNewMoaMetadataProvider( + metadataurl, + buildMetadataFilterChain(oaParam, metadataurl, cert), + oaFriendlyName, + timer, + new BasicParserPool()); + + if (httpProvider != null) + providersinuse.put(metadataurl, httpProvider); } else { - Logger.info(oaFriendlyName - + " is not a PVP2 Application skipping"); + Logger.info(metadataurl + " are already added."); } - } 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(); - } - } - } - } + } else { + Logger.info(oaFriendlyName + + " is not a PVP2 Application skipping"); + } + } catch (Throwable e) { + Logger.error( + "Failed to add Metadata (unhandled reason: " + + e.getMessage(), e); - } else - Logger.info("No Online-Application configuration found. PVP 2.1 metadata provider initialization failed!"); - - try { - chainProvider.setProviders(new ArrayList(providersinuse.values())); - - } catch (MetadataProviderException e) { - Logger.error( - "Failed to add Metadata (unhandled reason: " - + e.getMessage(), e); + if (httpProvider != null && httpProvider instanceof BaseMetadataProvider) { + Logger.debug("Destroy failed Metadata provider"); + ((BaseMetadataProvider)httpProvider).destroy(); + + } + } + } } - internalProvider = chainProvider; - - } catch (ConfigurationException e) { - Logger.error("Access MOA-ID configuration FAILED.", e); + } else + Logger.info("No Online-Application configuration found. PVP 2.1 metadata provider initialization failed!"); + + try { + chainProvider.setProviders(new ArrayList(providersinuse.values())); + } catch (MetadataProviderException e) { + Logger.error( + "Failed to add Metadata (unhandled reason: " + + e.getMessage(), e); } + + internalProvider = chainProvider; } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java index d5c7d9100..e060e18e1 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/SimpleMOAMetadataProvider.java @@ -22,15 +22,19 @@ */ package at.gv.egovernment.moa.id.protocols.pvp2x.metadata; +import java.io.File; import java.util.Timer; import javax.net.ssl.SSLHandshakeException; import org.apache.commons.httpclient.MOAHttpClient; +import org.apache.commons.httpclient.params.HttpClientParams; +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; -import org.opensaml.xml.parse.BasicParserPool; +import org.opensaml.xml.parse.ParserPool; +import org.springframework.beans.factory.annotation.Autowired; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.ex.MOAHttpProtocolSocketFactoryException; @@ -40,6 +44,7 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.filter.SchemaValidationException; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.filter.SignatureValidationException; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.FileUtils; /** * @author tlenz @@ -47,6 +52,104 @@ import at.gv.egovernment.moa.logging.Logger; */ public abstract class SimpleMOAMetadataProvider implements MetadataProvider{ + private static final String URI_PREFIX_HTTP = "http:"; + private static final String URI_PREFIX_HTTPS = "https:"; + private static final String URI_PREFIX_FILE = "file:"; + + + @Autowired + protected AuthConfiguration authConfig; + + /** + * Create a single SAML2 MOA specific 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 timer {@link Timer} which is used to schedule metadata refresh operations + * + * @return SAML2 Metadata Provider, or null if the metadata provider can not initialized + */ + protected MetadataProvider createNewMoaMetadataProvider(String metadataLocation, MetadataFilter filter, + String IdForLogging, Timer timer, ParserPool pool) { + if (metadataLocation.startsWith(URI_PREFIX_HTTP) || metadataLocation.startsWith(URI_PREFIX_HTTPS)) + return createNewHTTPMetaDataProvider(metadataLocation, filter, IdForLogging, timer, pool); + + else { + String absoluteMetadataLocation = FileUtils.makeAbsoluteURL( + metadataLocation, + authConfig.getRootConfigFileDir()); + + if (absoluteMetadataLocation.startsWith(URI_PREFIX_FILE)) { + File metadataFile = new File(absoluteMetadataLocation); + if (metadataFile.exists()) + return createNewFileSystemMetaDataProvider(metadataFile, filter, IdForLogging, timer, pool); + + else { + Logger.warn("SAML2 metadata file: " + absoluteMetadataLocation + " not found or not exist"); + return null; + } + + } + } + + Logger.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 + */ + private MetadataProvider createNewFileSystemMetaDataProvider(File metadataFile, MetadataFilter filter, String IdForLogging, Timer timer, ParserPool pool) { + FilesystemMetadataProvider fileSystemProvider = null; + try { + fileSystemProvider = new FilesystemMetadataProvider(timer, metadataFile); + fileSystemProvider.setParserPool(pool); + fileSystemProvider.setRequireValidMetadata(true); + fileSystemProvider.setMinRefreshDelay(1000*60*15); //15 minutes + fileSystemProvider.setMaxRefreshDelay(1000*60*60*24); //24 hours + //httpProvider.setRefreshDelayFactor(0.1F); + + fileSystemProvider.setMetadataFilter(filter); + fileSystemProvider.initialize(); + + fileSystemProvider.setRequireValidMetadata(true); + + return fileSystemProvider; + + } catch (Exception e) { + Logger.warn( + "Failed to load Metadata file for " + + IdForLogging + "[ " + + "File: " + metadataFile.getAbsolutePath() + + " Msg: " + e.getMessage() + " ]", e); + + + Logger.warn("Can not initialize SAML2 metadata provider from filesystem: " + metadataFile.getAbsolutePath() + + " Reason: " + e.getMessage(), e); + + if (fileSystemProvider != null) + fileSystemProvider.destroy(); + + } + + return null; + + } + + + /** * Create a single SAML2 HTTP metadata provider * @@ -54,16 +157,21 @@ public abstract class SimpleMOAMetadataProvider implements MetadataProvider{ * @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 */ - protected HTTPMetadataProvider createNewHTTPMetaDataProvider(String metadataURL, MetadataFilter filter, String IdForLogging, Timer timer) { + private MetadataProvider createNewHTTPMetaDataProvider(String metadataURL, MetadataFilter filter, String IdForLogging, Timer timer, ParserPool pool) { HTTPMetadataProvider httpProvider = null; //Timer timer= null; MOAHttpClient httpClient = null; try { httpClient = new MOAHttpClient(); + HttpClientParams httpClientParams = new HttpClientParams(); + httpClientParams.setSoTimeout(AuthConfiguration.CONFIG_PROPS_METADATA_SOCKED_TIMEOUT); + httpClient.setParams(httpClientParams); + if (metadataURL.startsWith("https:")) { try { //FIX: change hostname validation default flag to true when httpClient is updated to > 4.4 @@ -88,7 +196,7 @@ public abstract class SimpleMOAMetadataProvider implements MetadataProvider{ // timer = new Timer(true); httpProvider = new HTTPMetadataProvider(timer, httpClient, metadataURL); - httpProvider.setParserPool(new BasicParserPool()); + httpProvider.setParserPool(pool); httpProvider.setRequireValidMetadata(true); httpProvider.setMinRefreshDelay(1000*60*15); //15 minutes httpProvider.setMaxRefreshDelay(1000*60*60*24); //24 hours @@ -115,7 +223,7 @@ public abstract class SimpleMOAMetadataProvider implements MetadataProvider{ + metadataURL + " FAILED.", e); } - Logger.error( + Logger.warn( "Failed to load Metadata file for " + IdForLogging + "[ " + e.getMessage() + " ]", e); -- cgit v1.2.3