diff options
Diffstat (limited to 'id/server/modules/moa-id-module-eIDAS/src/main')
25 files changed, 886 insertions, 124 deletions
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java index 8471439e2..d93d739b1 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java @@ -22,6 +22,16 @@ */ package at.gv.egovernment.moa.id.auth.modules.eidas; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.opensaml.xml.encryption.EncryptionConstants; +import org.opensaml.xml.signature.SignatureConstants; + +import eu.eidas.auth.engine.core.eidas.EidasAttributesTypes; +import eu.eidas.auth.engine.core.validator.eidas.EIDASAttributes; + /** * @author tlenz * @@ -60,23 +70,55 @@ public class Constants { public static final long CONFIG_PROPS_METADATA_GARBAGE_TIMEOUT = 7 * 24 * 60 * 60 * 1000; //remove unused eIDAS metadata after 7 days //eIDAS attribute names - public static final String eIDAS_ATTR_PERSONALIDENTIFIER = "PersonIdentifier"; - public static final String eIDAS_ATTR_DATEOFBIRTH = "DateOfBirth"; - public static final String eIDAS_ATTR_CURRENTGIVENNAME = "CurrentGivenName"; - public static final String eIDAS_ATTR_CURRENTFAMILYNAME = "CurrentFamilyName"; + public static final String eIDAS_ATTR_PERSONALIDENTIFIER = EIDASAttributes.ATTRIBUTE_NAME_SUFFIX_PERSONIDENTIFIER; + public static final String eIDAS_ATTR_DATEOFBIRTH = EIDASAttributes.ATTRIBUTE_NAME_SUFFIX_DATEOFBIRTH; + public static final String eIDAS_ATTR_CURRENTGIVENNAME = EIDASAttributes.ATTRIBUTE_NAME_SUFFIX_FIRSTNAME; + public static final String eIDAS_ATTR_CURRENTFAMILYNAME = EIDASAttributes.ATTRIBUTE_NAME_SUFFIX_GIVENNAME; //http endpoint descriptions public static final String eIDAS_HTTP_ENDPOINT_SP_POST = "/eidas/sp/post"; public static final String eIDAS_HTTP_ENDPOINT_SP_REDIRECT = "/eidas/sp/redirect"; - public static final String eIDAS_HTTP_ENDPOINT_IDP_POST = "/eidas/idp/post"; + public static final String eIDAS_HTTP_ENDPOINT_IDP_POST = "/eidas/idp/post"; + public static final String eIDAS_HTTP_ENDPOINT_IDP_COLLEAGUEREQUEST = "/eidas/ColleagueRequest"; public static final String eIDAS_HTTP_ENDPOINT_IDP_REDIRECT = "/eidas/idp/redirect"; public static final String eIDAS_HTTP_ENDPOINT_METADATA = "/eidas/metadata"; + //Event-Codes for Revisionslog public static final int eIDAS_REVERSIONSLOG_METADATA = 3400; public static final int eIDAS_REVERSIONSLOG_IDP_AUTHREQUEST = 3401; public static final int eIDAS_REVERSIONSLOG_IDP_AUTHRESPONSE = 3402; public static final int eIDAS_REVERSIONSLOG_SP_AUTHREQUEST= 3403; public static final int eIDAS_REVERSIONSLOG_SP_AUTHRESPONSE= 3404; - + + //metadata constants + public final static Map<String, EidasAttributesTypes> METADATA_POSSIBLE_ATTRIBUTES = Collections.unmodifiableMap( + new HashMap<String, EidasAttributesTypes>(){ + private static final long serialVersionUID = 1L; + { + put(EIDASAttributes.ATTRIBUTE_GIVENNAME, EidasAttributesTypes.NATURAL_PERSON_MANDATORY); + put(EIDASAttributes.ATTRIBUTE_FIRSTNAME, EidasAttributesTypes.NATURAL_PERSON_MANDATORY); + put(EIDASAttributes.ATTRIBUTE_DATEOFBIRTH, EidasAttributesTypes.NATURAL_PERSON_MANDATORY); + put(EIDASAttributes.ATTRIBUTE_PERSONIDENTIFIER, EidasAttributesTypes.NATURAL_PERSON_MANDATORY); + + //TODO: add additional attributes for eIDAS with mandates + //put(EIDASAttributes.ATTRIBUTE_LEGALIDENTIFIER, EidasAttributesTypes.LEGAL_PERSON_MANDATORY); + //put(EIDASAttributes.ATTRIBUTE_LEGALNAME, EidasAttributesTypes.LEGAL_PERSON_MANDATORY); + } + } + ); + + public static final String METADATA_ALLOWED_ALG_DIGIST = + SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256 + ";" + + SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512 ; + + public static final String METADATA_ALLOWED_ALG_SIGN = + SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256 + ";" + + SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512; + + public static final String METADATA_ALLOWED_ALG_ENCRYPT = + EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM + ";" + + EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192_GCM + ";" + + EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM; + } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAIDCertificateManagerConfigurationImpl.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAIDCertificateManagerConfigurationImpl.java index 9b634ff4d..1759a7281 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAIDCertificateManagerConfigurationImpl.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAIDCertificateManagerConfigurationImpl.java @@ -54,7 +54,7 @@ public class MOAIDCertificateManagerConfigurationImpl extends try { initalizeConfiguration(); - } catch (at.gv.egovernment.moa.id.config.ConfigurationException e) { + } catch (at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException e) { Logger.error("eIDAS SAML-engine initialization FAILED", e); } @@ -89,7 +89,7 @@ public class MOAIDCertificateManagerConfigurationImpl extends try { initalizeConfiguration(); - } catch (at.gv.egovernment.moa.id.config.ConfigurationException e) { + } catch (at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException e) { Logger.error("eIDAS SAML-engine initialization FAILED", e); } @@ -103,10 +103,10 @@ public class MOAIDCertificateManagerConfigurationImpl extends /** * Initialize eIDAS SAML-engine from MOA-ID configuration - * @throws at.gv.egovernment.moa.id.config.ConfigurationException + * @throws at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException * */ - private void initalizeConfiguration() throws at.gv.egovernment.moa.id.config.ConfigurationException { + private void initalizeConfiguration() throws at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException { //initialize configuration MOAeIDASSAMLEngineConfigurationImpl tmp = new MOAeIDASSAMLEngineConfigurationImpl(); tmp.initialize(); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLEngineConfigurationImpl.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLEngineConfigurationImpl.java index 584910ea5..5d1874157 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLEngineConfigurationImpl.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAeIDASSAMLEngineConfigurationImpl.java @@ -37,7 +37,7 @@ import java.util.Properties; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineConfigurationException; -import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.FileUtils; diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/ModifiedEncryptionSW.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/ModifiedEncryptionSW.java index bdd8c8e72..1ba344fd1 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/ModifiedEncryptionSW.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/ModifiedEncryptionSW.java @@ -1,7 +1,7 @@ package at.gv.egovernment.moa.id.auth.modules.eidas.config; -import at.gv.egovernment.moa.id.config.ConfigurationException; -import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; +import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; +import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.logging.Logger; import eu.eidas.auth.engine.core.impl.EncryptionSW; diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/eIDASSignalServlet.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/eIDASSignalServlet.java index 2c0f1cf8c..16d909331 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/eIDASSignalServlet.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/eIDASSignalServlet.java @@ -24,7 +24,6 @@ package at.gv.egovernment.moa.id.auth.modules.eidas; import java.io.IOException; -import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -46,7 +45,8 @@ public class eIDASSignalServlet extends AbstractProcessEngineSignalController { public eIDASSignalServlet() { super(); Logger.debug("Registering servlet " + getClass().getName() + - " with mappings '/eidas/sp/post' and '/eidas/sp/redirect'."); + " with mappings '"+ Constants.eIDAS_HTTP_ENDPOINT_SP_POST + + "' and '"+ Constants.eIDAS_HTTP_ENDPOINT_SP_REDIRECT + "'."); } @@ -75,12 +75,13 @@ public class eIDASSignalServlet extends AbstractProcessEngineSignalController { // use SAML2 relayState if (sessionId == null) { sessionId = StringEscapeUtils.escapeHtml(request.getParameter("RelayState")); - } + } else + Logger.warn("No parameter 'SAMLResponse'. Unable to retrieve MOA session id."); // take from InResponseTo attribute of SAMLResponse - if (sessionId == null) { - String base64SamlToken = request.getParameter("SAMLResponse"); - if (base64SamlToken != null && false) { +// if (sessionId == null) { +// String base64SamlToken = request.getParameter("SAMLResponse"); +// if (base64SamlToken != null && false) { // byte[] samlToken = Base64Utils.decode(base64SamlToken, false); // Document samlResponse = parseDocument(new ByteArrayInputStream(samlToken)); // @@ -91,10 +92,10 @@ public class eIDASSignalServlet extends AbstractProcessEngineSignalController { // XPathExpression expression = xPath.compile("string(/saml2p:Response/@InResponseTo)"); // sessionId = (String) expression.evaluate(samlResponse, XPathConstants.STRING); // sessionId = StringEscapeUtils.escapeHtml(StringUtils.trimToNull(sessionId)); - } else { - Logger.warn("No parameter 'SAMLResponse'. Unable to retrieve MOA session id."); - } - } +// } else { +// Logger.warn("No parameter 'SAMLResponse'. Unable to retrieve MOA session id."); +// } +// } } catch (Exception e) { Logger.warn("Unable to retrieve moa session id.", e); 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 55504dcb0..80a2734f2 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 @@ -18,6 +18,7 @@ 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.FilterException; import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider; import org.opensaml.saml2.metadata.provider.MetadataFilter; import org.opensaml.saml2.metadata.provider.MetadataProvider; @@ -26,9 +27,9 @@ import org.opensaml.saml2.metadata.provider.ObservableMetadataProvider; import org.opensaml.xml.XMLObject; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.ex.MOAHttpProtocolSocketFactoryException; import at.gv.egovernment.moa.id.commons.utils.MOAHttpProtocolSocketFactory; -import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing; import at.gv.egovernment.moa.id.config.auth.MOAGarbageCollector; @@ -65,7 +66,7 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi private MOAeIDASChainingMetadataProvider() { internalProvider = new ChainingMetadataProvider(); lastAccess = new HashMap<String, Date>(); - + } /* (non-Javadoc) @@ -92,12 +93,13 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi } } - if (!expiredEntities.isEmpty()) { - ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; - - //get all actually loaded metadata providers - Map<String, HTTPMetadataProvider> loadedproviders = getAllActuallyLoadedProviders(); + ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; + boolean isUpdateRequired = false; + //get all actually loaded metadata providers + Map<String, HTTPMetadataProvider> loadedproviders = getAllActuallyLoadedProviders(); + + if (!expiredEntities.isEmpty()) { for (String expired : expiredEntities) { if (loadedproviders.containsKey(expired)) { HTTPMetadataProvider provider = loadedproviders.get(expired); @@ -107,7 +109,8 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi //remove from map loadedproviders.remove(expired); - + isUpdateRequired = true; + /*OpenSAML ChainingMetadataProvider can not remove a MetadataProvider (UnsupportedOperationException) *The ChainingMetadataProvider use internal a unmodifiableList to hold all registrated MetadataProviders.*/ //chainProvider.removeMetadataProvider(provider); @@ -118,18 +121,43 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi Logger.warn("eIDAS metadata for EntityID: " + expired + " is marked as unsed, but no loaded metadata provider is found."); - } + } + } + //check signature of all metadata which are actually loaded + List<String> nonValidMetadataProvider = new ArrayList<String>(); + for (HTTPMetadataProvider provider : loadedproviders.values()) { + try { + provider.getMetadataFilter().doFilter(provider.getMetadata()); + + } catch (FilterException | MetadataProviderException e) { + Logger.info("eIDAS MetadataProvider: " + provider.getMetadataURI() + + " is not valid any more. Reason:" + e.getMessage()); + if (Logger.isDebugEnabled()) + Logger.warn("Reason", e); + + nonValidMetadataProvider.add(provider.getMetadataURI()); + + } + } + for (String el : nonValidMetadataProvider) { + loadedproviders.remove(el); + isUpdateRequired = true; + + } + + //update chaining metadata-provider if it is required + if (isUpdateRequired) { try { synchronized (chainProvider) { chainProvider.setProviders(new ArrayList<MetadataProvider>(loadedproviders.values())); - + emitChangeEvent(); } - + } catch (MetadataProviderException e) { Logger.warn("ReInitalize eIDASA MetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy", e); - + } } } @@ -184,7 +212,7 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi httpProvider.setMetadataFilter(filter); httpProvider.initialize(); - + return httpProvider; } catch (Throwable e) { @@ -277,7 +305,7 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi } - + public boolean requireValidMetadata() { return internalProvider.requireValidMetadata(); } @@ -341,12 +369,22 @@ public class MOAeIDASChainingMetadataProvider implements ObservableMetadataProvi public List<RoleDescriptor> getRole(String entityID, QName roleName) throws MetadataProviderException { - return internalProvider.getRole(entityID, roleName); + EntityDescriptor entityDesc = getEntityDescriptor(entityID); + if (entityDesc != null) + return entityDesc.getRoleDescriptors(roleName); + + else + return null; } public RoleDescriptor getRole(String entityID, QName roleName, String supportedProtocol) throws MetadataProviderException { - return internalProvider.getRole(entityID, roleName, supportedProtocol); + EntityDescriptor entityDesc = getEntityDescriptor(entityID); + if (entityDesc != null) + return internalProvider.getRole(entityID, roleName, supportedProtocol); + + else + return null; } /* (non-Javadoc) 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 e3ae5c046..7537c4d84 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 @@ -94,6 +94,8 @@ public class MOAeIDASMetadataProviderDecorator implements MetadataProcessorI { throws SAMLEngineException { //Do nothing, because metadata signature is already validated during //metadata provider initialization + + //TODO: maybe signature validation is needed on every request } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDAsExtensionProcessor.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDAsExtensionProcessor.java new file mode 100644 index 000000000..5837d7dbf --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/engine/MOAeIDAsExtensionProcessor.java @@ -0,0 +1,48 @@ +/* + * 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.auth.modules.eidas.engine; + +import java.util.HashSet; +import java.util.Set; + +import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import eu.eidas.auth.engine.core.ExtensionProcessorI; +import eu.eidas.auth.engine.core.eidas.EidasExtensionProcessor; + +/** + * @author tlenz + * + */ +public class MOAeIDAsExtensionProcessor extends EidasExtensionProcessor implements ExtensionProcessorI { + + /** + * Add only eIDAS attributes which are supported by Austrian eIDAS node + * + */ + @Override + public Set<String> getSupportedAttributes(){ + Set<String> supportedAttributes=new HashSet<String>( Constants.METADATA_POSSIBLE_ATTRIBUTES.keySet()); + + return supportedAttributes; + } +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineConfigurationException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineConfigurationException.java index 98bc559d2..20f18b772 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineConfigurationException.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineConfigurationException.java @@ -22,7 +22,7 @@ */ package at.gv.egovernment.moa.id.auth.modules.eidas.exceptions; -import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; /** * @author tlenz diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineException.java index 95690bbeb..234c4e038 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineException.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/EIDASEngineException.java @@ -22,19 +22,21 @@ */ package at.gv.egovernment.moa.id.auth.modules.eidas.exceptions; +import org.opensaml.saml2.core.StatusCode; /** * @author tlenz * */ -public class EIDASEngineException extends Exception { +public class EIDASEngineException extends eIDASException { /** + * @param objects * @param string * @param e */ - public EIDASEngineException(String string, Throwable e) { - super(string, e); + public EIDASEngineException(String msg, Object[] objects, Throwable e) { + super(msg, objects, e); } /** @@ -42,4 +44,21 @@ public class EIDASEngineException extends Exception { */ private static final long serialVersionUID = 1559812927427153879L; + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASException#getStatusCodeFirstLevel() + */ + @Override + public String getStatusCodeFirstLevel() { + return StatusCode.RESPONDER_URI; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASException#getStatusCodeSecondLevel() + */ + @Override + public String getStatusCodeSecondLevel() { + return StatusCode.AUTHN_FAILED_URI; + } + } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAttributeException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAttributeException.java index 7840ae2e6..b25895eca 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAttributeException.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAttributeException.java @@ -22,17 +22,31 @@ */ package at.gv.egovernment.moa.id.auth.modules.eidas.exceptions; +import org.opensaml.saml2.core.StatusCode; + /** * @author tlenz * */ -public class eIDASAttributeException extends Exception { +public class eIDASAttributeException extends eIDASException { private static final long serialVersionUID = 1L; public eIDASAttributeException(String message) { - super(message); + super("eIDAS.07", new Object[]{message}); } + @Override + public String getStatusCodeFirstLevel() { + return StatusCode.RESPONDER_URI; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASException#getStatusCodeSecondLevel() + */ + @Override + public String getStatusCodeSecondLevel() { + return StatusCode.AUTHN_FAILED_URI; + } } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAuthnRequestProcessingException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAuthnRequestProcessingException.java new file mode 100644 index 000000000..c96af37ef --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAuthnRequestProcessingException.java @@ -0,0 +1,80 @@ +/* + * 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.auth.modules.eidas.exceptions; + +import org.opensaml.saml2.core.StatusCode; + +import at.gv.egovernment.moa.util.MiscUtil; + +/** + * @author tlenz + * + */ +public class eIDASAuthnRequestProcessingException extends eIDASException { + + private String subStatusCode = null; + + /** + * + */ + private static final long serialVersionUID = 1083563877689098041L; + + /** + * @param messageId + * @param parameters + */ + public eIDASAuthnRequestProcessingException(String messageId, Object[] parameters) { + super(messageId, parameters); + } + + public eIDASAuthnRequestProcessingException(String subStatusCode, String messageId, Object[] parameters) { + super(messageId, parameters); + this.subStatusCode = subStatusCode; + } + + public eIDASAuthnRequestProcessingException(String messageId, Object[] parameters, Throwable e) { + super(messageId, parameters, e ); + } + + public eIDASAuthnRequestProcessingException(String subStatusCode, String messageId, Object[] parameters, Throwable e) { + super(messageId, parameters, e ); + this.subStatusCode = subStatusCode; + } + + @Override + public String getStatusCodeFirstLevel() { + return StatusCode.REQUESTER_URI; + + } + + @Override + public String getStatusCodeSecondLevel() { + if (MiscUtil.isNotEmpty(subStatusCode)) + return subStatusCode; + + else + return StatusCode.REQUEST_DENIED_URI; + + } + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAuthnRequestValidationException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAuthnRequestValidationException.java new file mode 100644 index 000000000..2a15ee18a --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASAuthnRequestValidationException.java @@ -0,0 +1,59 @@ +/* + * 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.auth.modules.eidas.exceptions; + +import org.opensaml.saml2.core.StatusCode; + +/** + * @author tlenz + * + */ +public class eIDASAuthnRequestValidationException extends eIDASException { + + /** + * + */ + private static final long serialVersionUID = 4353716509546972267L; + + /** + * @param messageId + * @param parameters + */ + public eIDASAuthnRequestValidationException(String messageId, Object[] parameters) { + super(messageId, parameters); + + } + + @Override + public String getStatusCodeFirstLevel() { + return StatusCode.REQUESTER_URI; + + } + + @Override + public String getStatusCodeSecondLevel() { + return StatusCode.RESOURCE_NOT_RECOGNIZED_URI; + + } + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASException.java new file mode 100644 index 000000000..f42004abc --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASException.java @@ -0,0 +1,59 @@ +/* + * 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.auth.modules.eidas.exceptions; + +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; + +/** + * @author tlenz + * + */ +public abstract class eIDASException extends MOAIDException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + public abstract String getStatusCodeFirstLevel(); + public abstract String getStatusCodeSecondLevel(); + + + /** + * @param messageId + * @param parameters + */ + public eIDASException(String messageId, Object[] parameters) { + super(messageId, parameters); + } + + /** + * @param messageId + * @param parameters + */ + public eIDASException(String messageId, Object[] parameters, Throwable e) { + super(messageId, parameters, e); + } + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASResponseBuildException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASResponseBuildException.java new file mode 100644 index 000000000..0ffcf11ef --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASResponseBuildException.java @@ -0,0 +1,62 @@ +/* + * 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.auth.modules.eidas.exceptions; + +import org.opensaml.saml2.core.StatusCode; + +/** + * @author tlenz + * + */ +public class eIDASResponseBuildException extends eIDASException { + + /** + * + */ + private static final long serialVersionUID = 4446851988854996919L; + + /** + * @param messageId + * @param parameters + */ + public eIDASResponseBuildException(String messageId, Object[] parameters) { + super(messageId, parameters); + } + + public eIDASResponseBuildException(String messageId, Object[] parameters, Throwable e) { + super(messageId, parameters, e); + } + + @Override + public String getStatusCodeFirstLevel() { + return StatusCode.RESPONDER_URI; + + } + + @Override + public String getStatusCodeSecondLevel() { + return StatusCode.AUTHN_FAILED_URI; + + } + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASResponseNotSuccessException.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASResponseNotSuccessException.java new file mode 100644 index 000000000..d10ca1c88 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/exceptions/eIDASResponseNotSuccessException.java @@ -0,0 +1,67 @@ +/* + * 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.auth.modules.eidas.exceptions; + +import org.opensaml.saml2.core.StatusCode; + +/** + * @author tlenz + * + */ +public class eIDASResponseNotSuccessException extends eIDASException { + + /** + * + */ + private static final long serialVersionUID = 6145402939313568907L; + + public eIDASResponseNotSuccessException(String messageId, Object[] parameters) { + super(messageId, parameters); + } + + /** + * @param messageId + * @param parameters + * @param e + */ + public eIDASResponseNotSuccessException(String messageId, Object[] parameters, Throwable e) { + super(messageId, parameters, e); + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASException#getStatusCodeFirstLevel() + */ + @Override + public String getStatusCodeFirstLevel() { + return StatusCode.RESPONDER_URI; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASException#getStatusCodeSecondLevel() + */ + @Override + public String getStatusCodeSecondLevel() { + return StatusCode.AUTHN_FAILED_URI; + } + +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CreateIdentityLinkTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CreateIdentityLinkTask.java index 515ce2913..5d7430dd7 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CreateIdentityLinkTask.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/CreateIdentityLinkTask.java @@ -22,29 +22,25 @@ */ package at.gv.egovernment.moa.id.auth.modules.eidas.tasks; -import java.io.IOException; import java.io.InputStream; -import java.text.ParseException; import java.text.SimpleDateFormat; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.xml.parsers.ParserConfigurationException; import org.springframework.stereotype.Component; import org.w3c.dom.Element; import org.w3c.dom.Node; -import org.xml.sax.SAXException; import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants; import at.gv.egovernment.moa.id.auth.data.IdentityLink; -import at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASAttributeException; import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.id.process.api.ExecutionContext; import at.gv.egovernment.moa.id.util.IdentityLinkReSigner; @@ -94,28 +90,28 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask { // - set bpk/wpbk; Node prIdentification = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH); if(!eIDASAttributes.containsKey(Constants.eIDAS_ATTR_PERSONALIDENTIFIER)) - throw new eIDASAttributeException("PersonalIdentifier is missing"); + throw new eIDASAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER); String eIdentifier = eIDASAttributes.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER).getValue().get(0); prIdentification.getFirstChild().setNodeValue(eIdentifier); // - set last name Node prFamilyName = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_FAMILY_NAME_XPATH); if(!eIDASAttributes.containsKey(Constants.eIDAS_ATTR_CURRENTFAMILYNAME)) - throw new eIDASAttributeException("currentFamilyName is missing"); + throw new eIDASAttributeException(Constants.eIDAS_ATTR_CURRENTFAMILYNAME); String familyName = eIDASAttributes.get(Constants.eIDAS_ATTR_CURRENTFAMILYNAME).getValue().get(0); prFamilyName.getFirstChild().setNodeValue(familyName); // - set first name Node prGivenName = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_GIVEN_NAME_XPATH); if(!eIDASAttributes.containsKey(Constants.eIDAS_ATTR_CURRENTGIVENNAME)) - throw new eIDASAttributeException("currentGivenName is missing"); + throw new eIDASAttributeException(Constants.eIDAS_ATTR_CURRENTGIVENNAME); String givenName = eIDASAttributes.get(Constants.eIDAS_ATTR_CURRENTGIVENNAME).getValue().get(0); prGivenName.getFirstChild().setNodeValue(givenName); // - set date of birth Node prDateOfBirth = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_DATE_OF_BIRTH_XPATH); if(!eIDASAttributes.containsKey(Constants.eIDAS_ATTR_DATEOFBIRTH)) - throw new eIDASAttributeException("dateOfBirth is missing"); + throw new eIDASAttributeException(Constants.eIDAS_ATTR_DATEOFBIRTH); String dateOfBirth = eIDASAttributes.get(Constants.eIDAS_ATTR_DATEOFBIRTH).getValue().get(0); dateOfBirth = new SimpleDateFormat("yyyy-MM-dd").format(new SimpleDateFormat("yyyyMMdd").parse(dateOfBirth)); prDateOfBirth.getFirstChild().setNodeValue(dateOfBirth); @@ -149,15 +145,18 @@ public class CreateIdentityLinkTask extends AbstractAuthServletTask { //store MOA-session to database authenticatedSessionStorage.storeSession(moasession); - - } catch (ParseException | MOAIDException | MOADatabaseException | ParserConfigurationException | SAXException | IOException e) { - throw new TaskExecutionException(pendingReq, "IdentityLink generation for foreign person FAILED.", e); - + } catch (eIDASAttributeException e) { throw new TaskExecutionException(pendingReq, "Minimum required eIDAS attributeset not found.", e); - - } - + + } catch (MOAIDException | MOADatabaseException e) { + throw new TaskExecutionException(pendingReq, "IdentityLink generation for foreign person FAILED.", e); + + } catch (Exception e) { + Logger.error("IdentityLink generation for foreign person FAILED.", e); + throw new TaskExecutionException(pendingReq, "IdentityLink generation for foreign person FAILED.", e); + + } } } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java index 2156720e8..30c206025 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/GenerateAuthnRequestTask.java @@ -22,7 +22,6 @@ */ package at.gv.egovernment.moa.id.auth.modules.eidas.tasks; -import java.io.IOException; import java.io.StringWriter; import java.util.Collection; @@ -36,19 +35,22 @@ import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.springframework.stereotype.Component; -import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; +import com.google.common.net.MediaType; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; -import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.frontend.velocity.VelocityProvider; import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; -import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; -import at.gv.egovernment.moa.id.config.stork.CPEPS; -import at.gv.egovernment.moa.id.config.stork.StorkAttribute; +import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; +import at.gv.egovernment.moa.id.commons.api.data.CPEPS; +import at.gv.egovernment.moa.id.commons.api.data.StorkAttribute; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.id.process.api.ExecutionContext; -import at.gv.egovernment.moa.id.util.VelocityProvider; import at.gv.egovernment.moa.logging.Logger; import eu.eidas.auth.commons.EIDASAuthnRequest; import eu.eidas.auth.commons.EIDASUtil; @@ -85,18 +87,24 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask { if (StringUtils.isEmpty(citizenCountryCode)) { // illegal state; task should not have been executed without a selected country - throw new AuthenticationException("stork.22", new Object[] { pendingReq.getRequestID() }); + throw new AuthenticationException("eIDAS.03", new Object[] { "" }); } CPEPS cpeps = authConfig.getStorkConfig().getCPEPS(citizenCountryCode); if(null == cpeps) { Logger.error("PEPS unknown for country", new Object[] {citizenCountryCode}); - throw new AuthenticationException("Unknown PEPS for citizen country '{}'", new Object[] {citizenCountryCode}); + throw new AuthenticationException("eIDAS.04", new Object[] {citizenCountryCode}); } Logger.debug("Found eIDaS Node/C-PEPS configuration for citizen of country: " + citizenCountryCode); String destination = cpeps.getPepsURL().toString().split(";")[1].trim(); // FIXME convenience for metadata url and assertion destination String metadataUrl = cpeps.getPepsURL().toString().split(";")[0].trim(); + + //TODO: switch to entityID + revisionsLogger.logEvent(oaConfig, pendingReq, + MOAIDEventConstants.AUTHPROCESS_PEPS_SELECTED, + metadataUrl); + // assemble requested attributes Collection<StorkAttribute> attributesFromConfig = oaConfig.getRequestedSTORKAttributes(); @@ -132,7 +140,12 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask { authnRequest.setEidasNameidFormat(EIDASAuthnRequest.NAMEID_FORMAT_UNSPECIFIED); authnRequest.setEidasLoA(EidasLoaLevels.LOW.stringValue()); authnRequest.setEidasLoACompareType(EidasLoaCompareType.MINIMUM.stringValue()); - authnRequest.setSPType(SPType.DEFAULT_VALUE); + + //set correct SPType for this online application + if (oaConfig.getBusinessService()) + authnRequest.setSPType("private"); + else + authnRequest.setSPType(SPType.DEFAULT_VALUE); engine.initRequestedAttributes(pAttList); authnRequest = engine.generateEIDASAuthnRequest(authnRequest); @@ -165,27 +178,32 @@ public class GenerateAuthnRequestTask extends AbstractAuthServletTask { Logger.debug("Template merge done"); Logger.debug("Sending html content: " + writer.getBuffer().toString()); - - response.setContentType("text/html;charset=UTF-8"); + + response.setContentType(MediaType.HTML_UTF_8.toString()); response.getOutputStream().write(writer.getBuffer().toString().getBytes("UTF-8")); - } catch (IOException e) { - Logger.error("Velocity IO error: " + e.getMessage()); - throw new MOAIDException("stork.15", null); // TODO + revisionsLogger.logEvent(oaConfig, pendingReq, + MOAIDEventConstants.AUTHPROCESS_PEPS_REQUESTED, + authnRequest.getSamlId()); + } catch (Exception e) { Logger.error("Velocity general error: " + e.getMessage()); - throw new MOAIDException("stork.15", null); // TODO + throw new MOAIDException("eIDAS.02", new Object[]{e.getMessage()}, e); + } }catch (EIDASSAMLEngineException e){ - Logger.error("eIDAS AuthnRequest generation FAILED.", e); throw new TaskExecutionException(pendingReq, "eIDAS AuthnRequest generation FAILED.", - new EIDASEngineException("Could not generate token for Saml Request", e)); + new EIDASEngineException("eIDAS.00", new Object[]{e.getMessage()}, e)); - } catch (EIDASEngineException | MOAIDException e) { + } catch (MOAIDException e) { throw new TaskExecutionException(pendingReq, "eIDAS AuthnRequest generation FAILED.", e); - } + } catch (Exception e) { + Logger.error("eIDAS AuthnRequest generation FAILED.", e); + throw new TaskExecutionException(pendingReq, e.getMessage(), e); + + } } } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java index 9858d6004..fae06031a 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/tasks/ReceiveAuthnResponseTask.java @@ -3,16 +3,19 @@ package at.gv.egovernment.moa.id.auth.modules.eidas.tasks; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.opensaml.saml2.core.StatusCode; import org.springframework.stereotype.Component; +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants; -import at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASResponseNotSuccessException; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAPersonalAttributeList; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; import at.gv.egovernment.moa.id.process.api.ExecutionContext; import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; @@ -57,7 +60,15 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { //TODO: check if additional decryption operation is required } - + + //check response StatusCode + if (!samlResp.getStatusCode().equals(StatusCode.SUCCESS_URI)) { + Logger.info("Receice eIDAS Response with StatusCode:" + samlResp.getStatusCode() + + " Subcode:" + samlResp.getSubStatusCode() + " Msg:" + samlResp.getMessage()); + throw new eIDASResponseNotSuccessException("eIDAS.11", new Object[]{samlResp.getMessage()}); + + } + //MOA-ID specific response validation //TODO: implement MOA-ID specific response validation @@ -79,13 +90,29 @@ public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { //store MOA-session to database authenticatedSessionStorage.storeSession(moasession); + revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq, + MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED, + samlResp.getSamlId()); + }catch (EIDASSAMLEngineException e) { Logger.error("eIDAS AuthnRequest generation FAILED.", e); + revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq, + MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED_ERROR); + throw new TaskExecutionException(pendingReq, "eIDAS AuthnRequest generation FAILED.", + new EIDASEngineException("eIDAS.09", new Object[]{e.getMessage()}, e)); + + } catch (MOADatabaseException e) { + revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq, + MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED_ERROR); throw new TaskExecutionException(pendingReq, "eIDAS Response processing FAILED.", - new EIDASEngineException("Could not validate eIDAS response", e)); + new MOAIDException("init.04", new Object[]{""}, e)); - } catch (EIDASEngineException | MOAIDException | MOADatabaseException e) { - throw new TaskExecutionException(pendingReq, "eIDAS Response processing FAILED.", e); + } catch (Exception e) { + Logger.error("eIDAS Response processing FAILED.", e); + revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq, + MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED_ERROR); + throw new TaskExecutionException(pendingReq, e.getMessage(), + new MOAIDException("eIDAS.10", new Object[]{e.getMessage()}, e)); } 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 8e46f0ef1..eeb8305cf 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 @@ -26,9 +26,11 @@ import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; import at.gv.egovernment.moa.id.auth.modules.eidas.config.MOAIDCertificateManagerConfigurationImpl; import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider; import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASMetadataProviderDecorator; +import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDAsExtensionProcessor; import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException; import at.gv.egovernment.moa.logging.Logger; import eu.eidas.auth.engine.EIDASSAMLEngine; +import eu.eidas.auth.engine.core.ExtensionProcessorI; import eu.eidas.engine.exceptions.EIDASSAMLEngineException; import eu.eidas.samlengineconfig.CertificateConfigurationManager; @@ -51,16 +53,20 @@ public class SAMLEngineUtils { EIDASSAMLEngine engine = EIDASSAMLEngine.createSAMLEngine(Constants.eIDAS_SAML_ENGINE_NAME, configManager); - //set Metadata managment to eIDAS SAMLengine + //set metadata management to eIDAS SAMLengine engine.setMetadataProcessor( new MOAeIDASMetadataProviderDecorator( MOAeIDASChainingMetadataProvider.getInstance())); + + //set MOA specific extension processor + ExtensionProcessorI extensionProcessor = new MOAeIDAsExtensionProcessor(); + engine.setExtensionProcessor(extensionProcessor); eIDASEngine = engine; } catch (EIDASSAMLEngineException e) { Logger.error("eIDAS SAMLengine initialization FAILED!", e); - throw new EIDASEngineException("eIDAS SAMLengine initialization FAILED!", e); + throw new EIDASEngineException("eIDAS.00", new Object[]{e.getMessage()}, e); } } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java index 3c33b8d58..563c3a18c 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASData.java @@ -26,6 +26,8 @@ public class EIDASData extends RequestImpl { /** The ip address of the requester. */ private String remoteIPAddress; + private String remoteRelayState; + @Override public Collection<String> getRequestedAttributes() { // TODO Auto-generated method stub @@ -85,4 +87,22 @@ public class EIDASData extends RequestImpl { public void setRemoteAddress(String remoteIP) { remoteIPAddress = remoteIP; } + + /** + * Gets the remote relay state. + * + * @return the remote relay state + */ + public String getRemoteRelayState() { + return remoteRelayState; + } + + /** + * Sets the remote relay state. + * + * @param relayState the new remote relay state + */ + public void setRemoteRelayState(String relayState) { + remoteRelayState = relayState; + } } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java index 1e3b0f507..24134f1d9 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EIDASProtocol.java @@ -23,40 +23,66 @@ package at.gv.egovernment.moa.id.protocols.eidas; import java.io.IOException; +import java.io.StringWriter; +import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.opensaml.saml2.core.StatusCode; +import org.opensaml.saml2.metadata.AssertionConsumerService; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; -import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; -import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.frontend.velocity.VelocityProvider; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider; +import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASMetadataProviderDecorator; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASAuthnRequestProcessingException; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASAuthnRequestValidationException; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASException; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAPersonalAttributeList; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; -import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; -import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; +import at.gv.egovernment.moa.id.commons.api.IRequest; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.id.moduls.RequestImpl; import at.gv.egovernment.moa.id.protocols.AbstractAuthProtocolModulController; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; import eu.eidas.auth.commons.EIDASAuthnRequest; +import eu.eidas.auth.commons.EIDASAuthnResponse; import eu.eidas.auth.commons.EIDASUtil; import eu.eidas.auth.engine.EIDASSAMLEngine; +import eu.eidas.auth.engine.metadata.MetadataUtil; +import eu.eidas.engine.exceptions.EIDASSAMLEngineException; /** - * eIDAS Protocol Support for outbound authentication + * eIDAS Protocol Support for outbound authentication and metadata generation * * @author tlenz */ +@Controller public class EIDASProtocol extends AbstractAuthProtocolModulController { public static final String NAME = EIDASProtocol.class.getName(); public static final String PATH = "eidas"; + public EIDASProtocol() { + super(); + Logger.debug("Registering servlet " + getClass().getName() + + " with mappings '" + Constants.eIDAS_HTTP_ENDPOINT_METADATA + + "' and '" + Constants.eIDAS_HTTP_ENDPOINT_IDP_COLLEAGUEREQUEST + + "' and '" + Constants.eIDAS_HTTP_ENDPOINT_IDP_POST +"'."); + + } + public String getName() { return NAME; } @@ -130,7 +156,7 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { First request step - send it to BKU selection for user authentication. After the user credentials and other info are obtained, in the second step the request will be processed and the user redirected */ - public void preProcess(HttpServletRequest request, HttpServletResponse response, EIDASData pendingReq) throws MOAIDException { + private void preProcess(HttpServletRequest request, HttpServletResponse response, EIDASData pendingReq) throws MOAIDException { Logger.info("received an eIDaS request"); @@ -152,6 +178,10 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { // - memorize remote ip pendingReq.setRemoteAddress(request.getRemoteAddr()); + // - memorize relaystate + String relayState = request.getParameter("RelayState"); + pendingReq.setRemoteRelayState(relayState); + // - memorize country code of target country pendingReq.setGenericDataToSession( RequestImpl.eIDAS_GENERIC_REQ_DATA_COUNTRY, samlReq.getCountry()); @@ -163,24 +193,142 @@ public class EIDASProtocol extends AbstractAuthProtocolModulController { samlReq.setPersonalAttributeList(pendingReq.getEidasRequestedAttributes()); // circumvent non-serializable eidas personal attribute list pendingReq.setEidasRequest(samlReq); + //validate destination against metadata + String reqDestination = samlReq.getDestination(); + if (MiscUtil.isNotEmpty(reqDestination)) { + boolean isValid = false; + List<AssertionConsumerService> allowedAssertionConsumerUrl = new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance()) + .getSPSSODescriptor(samlReq.getIssuer()).getAssertionConsumerServices(); + + for (AssertionConsumerService el : allowedAssertionConsumerUrl) { + if (reqDestination.equals(el.getLocation())) + isValid = true; + + } + + if (!isValid) { + Logger.info("eIDAS AuthnRequest contains a not valid 'Destination' attribute"); + throw new eIDASAuthnRequestValidationException("stork.01", + new Object[]{"eIDAS AuthnRequest contains a not valid 'Destination' attribute"}); + } + + } + + // - memorize OA url pendingReq.setOAURL(samlReq.getIssuer()); // - memorize OA config - OAAuthParameter oaConfig = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(pendingReq.getOAURL()); + IOAAuthParameters oaConfig = authConfig.getOnlineApplicationParameter(pendingReq.getOAURL()); if (oaConfig == null) - throw new AuthenticationException("stork.12", new Object[]{pendingReq.getOAURL()}); + throw new eIDASAuthnRequestProcessingException("eIDAS.08", new Object[]{pendingReq.getOAURL()}); + pendingReq.setOnlineApplicationConfiguration(oaConfig); + String spType = samlReq.getSPType(); + if (MiscUtil.isEmpty(spType)) { + Logger.info("Load SPType from metadata ... IS NOT IMPLEMENTED YET!!!"); + //TODO: maybe implement this if required + + } + + Logger.debug("eIDAS request has SPType:" + spType); + + } catch (MOAIDException e) { + Logger.info("eIDAS AuthnRequest preProcessing FAILED. Msg:" + e.getMessage()); + throw e; + + } catch (EIDASSAMLEngineException e) { + Logger.info("eIDAS AuthnRequest preProcessing FAILED. Msg:" + e.getMessage()); + throw new eIDASAuthnRequestProcessingException("eIDAS.06", new Object[]{e.getMessage()}, e); + } catch(Exception e) { - Logger.error("error in preprocessing step", e); - throw new MOAIDException("error in preprocessing step", null); + Logger.warn("eIDAS AuthnRequest preProcessing FAILED. Msg:" + e.getMessage(), e); + throw new eIDASAuthnRequestProcessingException("eIDAS.06", new Object[]{e.getMessage()}, e); } } - public boolean generateErrorMessage(Throwable e, HttpServletRequest request, HttpServletResponse response, IRequest protocolRequest) throws Throwable { - return false; + public boolean generateErrorMessage(Throwable e, HttpServletRequest request, HttpServletResponse response, IRequest pendingReq) throws Throwable { + if (pendingReq != null && pendingReq instanceof EIDASData) { + EIDASData eidasReq = (EIDASData) pendingReq; + if (eidasReq.getEidasRequest() == null) { + Logger.info("Can not build eIDAS ErrorResponse. No eIDAS AuthnRequest found."); + return false; + } + + try { + EIDASAuthnResponse eIDASResp = new EIDASAuthnResponse(); + eIDASResp.setIssuer(pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_METADATA); + + if (e instanceof eIDASException) { + eIDASResp.setStatusCode(((eIDASException) e).getStatusCodeFirstLevel()); + eIDASResp.setSubStatusCode(((eIDASException) e).getStatusCodeSecondLevel()); + eIDASResp.setMessage(e.getMessage()); + + } else if (e instanceof MOAIDException ) { + eIDASResp.setStatusCode(StatusCode.RESPONDER_URI); + eIDASResp.setSubStatusCode(StatusCode.AUTHN_FAILED_URI); + eIDASResp.setMessage(e.getMessage()); + + } else { + eIDASResp.setStatusCode(StatusCode.RESPONDER_URI); + eIDASResp.setSubStatusCode(StatusCode.AUTHN_FAILED_URI); + eIDASResp.setMessage(e.getMessage()); + + } + + + EIDASSAMLEngine engine = SAMLEngineUtils.createSAMLEngine(); + + if(null == eidasReq.getEidasRequest().getAssertionConsumerServiceURL()) { + String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata( + new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance()), + engine, + eidasReq.getEidasRequest()); + eidasReq.getEidasRequest().setAssertionConsumerServiceURL(assertionConsumerUrl); + + } + //get eIDAS SAML-engine + + eIDASResp = engine.generateEIDASAuthnResponseFail(eidasReq.getEidasRequest(), eIDASResp, + eidasReq.getRemoteAddress(), true); + + String token = EIDASUtil.encodeSAMLToken(eIDASResp.getTokenSaml()); + + VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine(); + Template template = velocityEngine.getTemplate("/resources/templates/stork2_postbinding_template.html"); + VelocityContext context = new VelocityContext(); + + context.put("RelayState", eidasReq.getRemoteRelayState()); + + context.put("SAMLResponse", token); + Logger.debug("SAMLResponse original: " + token); + + Logger.debug("Putting assertion consumer url as action: " + eidasReq.getEidasRequest().getAssertionConsumerServiceURL()); + context.put("action", eidasReq.getEidasRequest().getAssertionConsumerServiceURL()); + Logger.trace("Starting template merge"); + StringWriter writer = new StringWriter(); + + Logger.trace("Doing template merge"); + template.merge(context, writer); + Logger.trace("Template merge done"); + + Logger.trace("Sending html content : " + new String(writer.getBuffer())); + + response.getOutputStream().write(writer.getBuffer().toString().getBytes("UTF-8")); + response.setContentType(MediaType.TEXT_HTML.getType()); + + return true; + + } catch (Exception e1 ) { + Logger.error("Generate eIDAS Error-Response failed.", e); + + } + + } + + return false; } public boolean validate(HttpServletRequest request, HttpServletResponse response, IRequest pending) { diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java index 4e34902e2..b4db5c83d 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/EidasMetaDataRequest.java @@ -16,22 +16,29 @@ *******************************************************************************/ package at.gv.egovernment.moa.id.protocols.eidas; +import java.util.List; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.slf4j.Logger; +import org.opensaml.saml2.metadata.ContactPerson; +import org.opensaml.saml2.metadata.Organization; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; -import at.gv.egovernment.moa.id.auth.exception.MOAIDException; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; +import at.gv.egovernment.moa.id.commons.api.IRequest; +import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.SLOInformationInterface; import at.gv.egovernment.moa.id.moduls.IAction; -import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration; +import at.gv.egovernment.moa.logging.Logger; import eu.eidas.auth.engine.EIDASSAMLEngine; +import eu.eidas.auth.engine.metadata.Contact; import eu.eidas.auth.engine.metadata.MetadataConfigParams; import eu.eidas.auth.engine.metadata.MetadataGenerator; import eu.eidas.engine.exceptions.SAMLEngineException; @@ -42,7 +49,6 @@ import eu.eidas.engine.exceptions.SAMLEngineException; */ @Service("EidasMetaDataRequest") public class EidasMetaDataRequest implements IAction { - private Logger logger = org.slf4j.LoggerFactory.getLogger(EidasMetaDataRequest.class); /* (non-Javadoc) * @see at.gv.egovernment.moa.id.moduls.IAction#processRequest(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.data.IAuthData) @@ -52,9 +58,7 @@ public class EidasMetaDataRequest implements IAction { HttpServletRequest httpReq, HttpServletResponse httpResp, IAuthData authData) throws MOAIDException { - try { - logger.debug("EidasMetaDataServlet GET"); - + try { String pubURLPrefix = req.getAuthURL(); String metadata_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_METADATA; @@ -62,13 +66,15 @@ public class EidasMetaDataRequest implements IAction { String sp_return_url = pubURLPrefix + Constants.eIDAS_HTTP_ENDPOINT_SP_POST; String metaData = generateMetadata(metadata_url, sp_return_url); - logger.trace(metaData); + Logger.trace(metaData); - httpResp.setContentType(MediaType.TEXT_XML.getType()); + httpResp.setContentType(MediaType.APPLICATION_XML.getType()); httpResp.getWriter().print(metaData); httpResp.flushBuffer(); - } catch (Exception e) { - e.printStackTrace(); + } catch (Exception e) { + Logger.error("eIDAS Metadata generation FAILED.", e); + throw new MOAIDException("eIDAS.05", new Object[]{e.getMessage()}, e); + } @@ -103,15 +109,53 @@ public class EidasMetaDataRequest implements IAction { MetadataConfigParams mcp=new MetadataConfigParams(); generator.setConfigParams(mcp); generator.initialize(engine); - mcp.setEntityID(metadata_url); - + + mcp.setEntityID(metadata_url); + mcp.setAssertionConsumerUrl(sp_return_url); + + + //TODO: make it configurable + mcp.setAuthnRequestsSigned(true); + mcp.setWantAssertionsSigned(true); + mcp.setAssuranceLevel("http://eidas.europa.eu/LoA/substantial"); + + //must be set in request, because it could be different for every online-application + //mcp.setSpType(SPType.DEFAULT_VALUE); + + mcp.setDigestMethods(Constants.METADATA_ALLOWED_ALG_DIGIST); + mcp.setSigningMethods(Constants.METADATA_ALLOWED_ALG_SIGN); + mcp.setEncryptionAlgorithms(Constants.METADATA_ALLOWED_ALG_ENCRYPT); + + //add organisation information from PVP metadata information + Organization pvpOrganisation = null; + try { + pvpOrganisation = PVPConfiguration.getInstance().getIDPOrganisation(); + Contact technicalContact = new Contact(); + + List<ContactPerson> contacts = PVPConfiguration.getInstance().getIDPContacts(); + if (contacts != null && contacts.size() >= 1) { + technicalContact.setEmail(contacts.get(0).getEmailAddresses().get(0).getAddress()); + technicalContact.setGivenName(contacts.get(0).getGivenName().getName()); + technicalContact.setSurName(contacts.get(0).getSurName().getName()); + technicalContact.setPhone(contacts.get(0).getTelephoneNumbers().get(0).getNumber()); + mcp.setTechnicalContact(technicalContact ); + + } + + if (pvpOrganisation != null) { + mcp.setNodeUrl(pvpOrganisation.getURLs().get(0).getURL().getLocalString()); + mcp.setCountryName("Austria"); + technicalContact.setCompany(pvpOrganisation.getDisplayNames().get(0).getName().getLocalString()); + } + + } catch (ConfigurationException | NullPointerException e) { + Logger.warn("Can not load Organisation or Contact from Configuration", e); + + } + generator.addSPRole(); - String returnUrl = sp_return_url; - mcp.setAssertionConsumerUrl(returnUrl); - generator.addIDPRole(); - mcp.setAssuranceLevel("http://eidas.europa.eu/LoA/substantial"); // TODO make configurable - + metadata = generator.generateMetadata(); return metadata; } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java index 5f3f89aee..9943cc5fb 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/protocols/eidas/eIDASAuthenticationRequest.java @@ -37,17 +37,17 @@ import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; -import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.frontend.velocity.VelocityProvider; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider; import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASMetadataProviderDecorator; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAPersonalAttributeList; import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; +import at.gv.egovernment.moa.id.commons.api.IRequest; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; import at.gv.egovernment.moa.id.data.IAuthData; import at.gv.egovernment.moa.id.data.SLOInformationInterface; import at.gv.egovernment.moa.id.moduls.IAction; -import at.gv.egovernment.moa.id.moduls.IRequest; -import at.gv.egovernment.moa.id.util.VelocityProvider; import at.gv.egovernment.moa.logging.Logger; import eu.eidas.auth.commons.EIDASAuthnResponse; import eu.eidas.auth.commons.EIDASStatusCode; @@ -122,19 +122,21 @@ public class eIDASAuthenticationRequest implements IAction { // but we need to set the appropriate request issuer engine.setRequestIssuer(eidasRequest.getEidasRequest().getIssuer()); - // check if we have the destination available, supply it if not + if(null == eidasRequest.getEidasRequest().getAssertionConsumerServiceURL()) { String assertionConsumerUrl = MetadataUtil.getAssertionUrlFromMetadata( new MOAeIDASMetadataProviderDecorator(MOAeIDASChainingMetadataProvider.getInstance()), engine, eidasRequest.getEidasRequest()); eidasRequest.getEidasRequest().setAssertionConsumerServiceURL(assertionConsumerUrl); + } response = engine.generateEIDASAuthnResponse(eidasRequest.getEidasRequest(), response, eidasRequest.getRemoteAddress(), true); token = EIDASUtil.encodeSAMLToken(response.getTokenSaml()); + } catch(Exception e) { e.printStackTrace(); } @@ -146,7 +148,9 @@ public class eIDASAuthenticationRequest implements IAction { VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine(); Template template = velocityEngine.getTemplate("/resources/templates/stork2_postbinding_template.html"); VelocityContext context = new VelocityContext(); - + + context.put("RelayState", eidasRequest.getRemoteRelayState()); + context.put("SAMLResponse", token); Logger.debug("SAMLResponse original: " + token); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/resources/moaid_eidas_auth.beans.xml b/id/server/modules/moa-id-module-eIDAS/src/main/resources/moaid_eidas_auth.beans.xml index a3f5042a1..5d79d082a 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/resources/moaid_eidas_auth.beans.xml +++ b/id/server/modules/moa-id-module-eIDAS/src/main/resources/moaid_eidas_auth.beans.xml @@ -9,6 +9,11 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> + <bean id="eIDASSignalServlet" + class="at.gv.egovernment.moa.id.auth.modules.eidas.eIDASSignalServlet"/> + + <bean id="EIDASProtocol" + class="at.gv.egovernment.moa.id.protocols.eidas.EIDASProtocol"/> <!-- Authentication Process Tasks --> <bean id="GenerateAuthnRequestTask" |