diff options
6 files changed, 160 insertions, 26 deletions
| diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java index 8abf29703..28d74075e 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAEidasProtocolProcesser.java @@ -58,5 +58,11 @@ public class MOAEidasProtocolProcesser extends EidasProtocolProcessor {      public String getResponseValidatorId() {          return OWN_EIDAS_RESPONSE_VALIDATOR_SUITE_ID;      } -			 +	 +     +    public MetadataFetcherI getMetadataFetcher() { +    	return this.metadataFetcher; +    } +     +      } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAProtocolEngine.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAProtocolEngine.java index d8fcd1694..f347022b8 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAProtocolEngine.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAProtocolEngine.java @@ -1,16 +1,17 @@  package at.gv.egovernment.moa.id.auth.modules.eidas.engine; -import java.security.cert.X509Certificate; - -import org.apache.commons.lang3.StringUtils; +import org.opensaml.saml2.core.AuthnRequest;  import org.opensaml.saml2.core.Response; +import org.w3c.dom.Document;  import at.gv.egovernment.moa.logging.Logger; -import eu.eidas.auth.commons.EidasErrorKey; -import eu.eidas.auth.commons.protocol.IAuthenticationRequest; +import at.gv.egovernment.moa.util.MiscUtil; +import eu.eidas.auth.engine.Correlated;  import eu.eidas.auth.engine.ProtocolEngine;  import eu.eidas.auth.engine.configuration.ProtocolConfigurationAccessor; -import eu.eidas.auth.engine.xml.opensaml.SAMLEngineUtils; +import eu.eidas.auth.engine.core.ProtocolProcessorI; +import eu.eidas.auth.engine.metadata.MetadataFetcherI; +import eu.eidas.auth.engine.xml.opensaml.XmlSchemaUtil;  import eu.eidas.engine.exceptions.EIDASSAMLEngineException;  public class MOAProtocolEngine extends ProtocolEngine { @@ -20,6 +21,98 @@ public class MOAProtocolEngine extends ProtocolEngine {  	} +	/** +	 * Add SAML2 metadata refresh functionality if first validation failed  +	 *  +	 */ +	@Override +	public Correlated unmarshallResponse(byte[] responseBytes) throws EIDASSAMLEngineException { +		try { +			return super.unmarshallResponse(responseBytes); +			 +		} catch (EIDASSAMLEngineException e) { +			if (responseBytes != null ) { +				Logger.info("eIDAS Response validation FAILED. Starting metadata reloading process ..."); +				Document document = XmlSchemaUtil.validateSamlSchema(responseBytes); +				Response response = (Response) unmarshall(document); +				String entityID = response.getIssuer().getValue(); +				 +				if (MiscUtil.isEmpty(entityID)) { +					Logger.debug("eIDAS Response contains no EntityID."); +					throw e; +					 +				} +				 +				if (startInternalMetadataRefesh(entityID)) { +					Logger.debug("Metadata refresh success. Revalidate eIDAS Response ..."); +					return super.unmarshallResponse(responseBytes); +					 +				} +				Logger.info("eIDAS metadata refresh not possible or not successful."); +				 +			}			 +			throw e; +			 +		} +	} +	 +	/** +	 * Add SAML2 metadata refresh functionality if first validation failed  +	 *  +	 */ +	@Override +	public AuthnRequest unmarshallRequest(byte[] requestBytes) throws EIDASSAMLEngineException { +		try { +			return super.unmarshallRequest(requestBytes); +			 +			 +		} catch (EIDASSAMLEngineException e) { +			if (null != requestBytes) { +				Logger.info("eIDAS Request validation FAILED. Starting metadata reloading process ..."); +				Document document = XmlSchemaUtil.validateSamlSchema(requestBytes); +				AuthnRequest request = (AuthnRequest) unmarshall(document); +				String entityID = request.getIssuer().getValue(); +				 +				if (MiscUtil.isEmpty(entityID)) { +					Logger.debug("eIDAS Authn. Request contains no EntityID."); +					throw e; +					 +				} + +				if (startInternalMetadataRefesh(entityID)) { +					Logger.debug("Metadata refresh success. Revalidate eIDAS Authn. Request ..."); +					return super.unmarshallRequest(requestBytes); +					 +				} +				 +				Logger.info("eIDAS metadata refresh not possible or not successful."); +			} +			 +			throw e; +						 +		} +	} +	 +	/** +	 * Refresh SAML2 metadata if the internal metadata provider supports this functionality +	 *  +	 * @param entityID +	 * @return true if refresh was success, otherwise false +	 */ +	private boolean startInternalMetadataRefesh(String entityID) { +		//check if eIDAS SAML-Engine implementation supports metadata refresh +		ProtocolProcessorI protocolProcessor = this.getProtocolProcessor(); +		if (protocolProcessor instanceof MOAEidasProtocolProcesser) { +			MetadataFetcherI metadataFetcher =  +					((MOAEidasProtocolProcesser)protocolProcessor).getMetadataFetcher(); +			if (metadataFetcher instanceof MOAeIDASMetadataProviderDecorator)					 +				return ((MOAeIDASMetadataProviderDecorator)metadataFetcher).refreshMetadata(entityID); +				 +		} +		 +		return false; +	} +	  //	@Override  //	protected X509Certificate getEncryptionCertificate(String requestIssuer,  //			String destinationCountryCode) throws EIDASSAMLEngineException { diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java index ffa74b92b..75d57e615 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASChainingMetadataProvider.java @@ -35,6 +35,7 @@ import at.gv.egovernment.moa.id.commons.utils.MOAHttpProtocolSocketFactory;  import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;  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.id.protocols.pvp2x.metadata.IMOARefreshableMetadataProvider;  import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.MOASPMetadataSignatureFilter;  import at.gv.egovernment.moa.id.saml2.MetadataFilterChain;  import at.gv.egovernment.moa.logging.Logger; @@ -43,7 +44,7 @@ import eu.eidas.auth.engine.AbstractProtocolEngine;  @Service("eIDASMetadataProvider")  public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvider,  -	IGarbageCollectorProcessing, IDestroyableObject { +	IGarbageCollectorProcessing, IDestroyableObject, IMOARefreshableMetadataProvider {  //	private static MOAeIDASChainingMetadataProvider instance = null;  	private static Object mutex = new Object(); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataProviderDecorator.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataProviderDecorator.java index c5e56502b..9adc221e5 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataProviderDecorator.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDASMetadataProviderDecorator.java @@ -31,6 +31,7 @@ import org.opensaml.saml2.metadata.SPSSODescriptor;  import org.opensaml.saml2.metadata.provider.MetadataProvider;  import org.opensaml.saml2.metadata.provider.MetadataProviderException; +import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IMOARefreshableMetadataProvider;  import eu.eidas.auth.engine.ProtocolEngineI;  import eu.eidas.auth.engine.metadata.MetadataFetcherI;  import eu.eidas.auth.engine.metadata.MetadataSignerI; @@ -54,6 +55,23 @@ public class MOAeIDASMetadataProviderDecorator implements MetadataFetcherI {  	} +	/** +	 * Refresh the SAML2 metadata of a specific Entity +	 * <br> +	 * <b>Info:</b> A refresh is only possible if the internal metadata provider implements  +	 * the 'RefeshableMetadataProvider' interface +	 *     +	 * @param entityId EntityID that should be refreshed +	 * @return true if refresh was successful, otherwise false +	 */ +	public boolean refreshMetadata(String entityId) { +		if (this.metadataprovider instanceof IMOARefreshableMetadataProvider ) +			return ((IMOARefreshableMetadataProvider)this.metadataprovider).refreshMetadataProvider(entityId);		 +		else +			return false; +		 +	} +	  	/* (non-Javadoc)  	 * @see eu.eidas.auth.engine.metadata.MetadataFetcherI#getEntityDescriptor(java.lang.String, eu.eidas.auth.engine.metadata.MetadataSignerI)  	 */ diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAProtocolEngineFactory.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAProtocolEngineFactory.java index 47cdb4ade..dbe11c12e 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAProtocolEngineFactory.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAProtocolEngineFactory.java @@ -23,10 +23,16 @@  package at.gv.egovernment.moa.id.auth.modules.eidas.utils;  import at.gv.egovernment.moa.id.auth.modules.eidas.config.MOAIDCertificateManagerConfigurationImpl; +import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAProtocolEngine;  import at.gv.egovernment.moa.logging.Logger;  import eu.eidas.auth.engine.ProtocolEngineFactory; +import eu.eidas.auth.engine.ProtocolEngineI; +import eu.eidas.auth.engine.SamlEngineClock; +import eu.eidas.auth.engine.configuration.FixedProtocolConfigurationAccessor; +import eu.eidas.auth.engine.configuration.ProtocolEngineConfiguration;  import eu.eidas.auth.engine.configuration.SamlEngineConfigurationException;  import eu.eidas.auth.engine.configuration.dom.ProtocolEngineConfigurationFactory; +import eu.eidas.auth.engine.core.ProtocolProcessorI;  import eu.eidas.samlengineconfig.CertificateConfigurationManager;  /** @@ -95,22 +101,32 @@ public class MOAProtocolEngineFactory extends ProtocolEngineFactory {  	} -//	public static ProtocolEngineI createProtocolEngine(String instanceName, -//			ProtocolEngineConfigurationFactory protocolEngineConfigurationFactory, -//			ProtocolProcessorI protocolProcessor, SamlEngineClock samlEngineClock) -//					throws SamlEngineConfigurationException { -//	 -//		ProtocolEngineConfiguration preConfiguration = protocolEngineConfigurationFactory -//				.getConfiguration(instanceName); -// -//		protocolProcessor.configure(); -// -//		ProtocolEngineConfiguration configuration = ProtocolEngineConfiguration.builder(preConfiguration) -//				.protocolProcessor(protocolProcessor).clock(samlEngineClock).build(); -// -//		ProtocolEngineI samlEngine = new MOAProtocolEngine(new FixedProtocolConfigurationAccessor(configuration)); -// -//		return samlEngine; -//	} +	public static ProtocolEngineI ownCreateProtocolEngine(String instanceName, +			CertificateConfigurationManager configManager, ProtocolProcessorI protocolProcessor, +			SamlEngineClock samlEngineClock) throws SamlEngineConfigurationException { +		ProtocolEngineConfigurationFactory protocolEngineConfigurationFactory = new ProtocolEngineConfigurationFactory( +				configManager); + +		return createProtocolEngine(instanceName, protocolEngineConfigurationFactory, protocolProcessor, +				samlEngineClock); +	} +	 +	public static ProtocolEngineI createProtocolEngine(String instanceName, +			ProtocolEngineConfigurationFactory protocolEngineConfigurationFactory, +			ProtocolProcessorI protocolProcessor, SamlEngineClock samlEngineClock) +					throws SamlEngineConfigurationException { +	 +		ProtocolEngineConfiguration preConfiguration = protocolEngineConfigurationFactory +				.getConfiguration(instanceName); + +		protocolProcessor.configure(); + +		ProtocolEngineConfiguration configuration = ProtocolEngineConfiguration.builder(preConfiguration) +				.protocolProcessor(protocolProcessor).clock(samlEngineClock).build(); + +		ProtocolEngineI samlEngine = new MOAProtocolEngine(new FixedProtocolConfigurationAccessor(configuration)); + +		return samlEngine; +	}  } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java index edbecc4a0..773e08ea9 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java @@ -93,7 +93,7 @@ public class SAMLEngineUtils {  				}  				//build eIDAS SAML eninge -				ProtocolEngineI engine = MOAProtocolEngineFactory.createProtocolEngine( +				ProtocolEngineI engine = MOAProtocolEngineFactory.ownCreateProtocolEngine(  						Constants.eIDAS_SAML_ENGINE_NAME,   						configManager,   						new MOAEidasProtocolProcesser(metadataFetcher, metadataSigner, addAttrDefinitions),  | 
