From de03adfbe79968f65bb711d7b3a583eeb1054140 Mon Sep 17 00:00:00 2001 From: Alexander Marsalek Date: Mon, 1 Feb 2021 09:42:38 +0100 Subject: more transitions & tests --- .../specific/modules/auth/eidas/v2/Constants.java | 8 + .../v2/exception/InvalidUserInputException.java | 33 +++ .../IdAustriaAuthPvpConfiguration.java | 121 ++++++++++ .../IdAustriaClientAuthCredentialProvider.java | 2 +- .../GenerateMobilePhoneSignatureRequestTask.java | 3 - .../auth/eidas/v2/tasks/InitialSearchTask.java | 6 +- .../ReceiveGuiAustrianResidenceResponseTask.java | 79 ++++-- .../eidas/v2/tasks/ReceiveGuiResponseTask.java | 16 +- ...eSignatureResponseAndSearchInRegistersTask.java | 266 ++++++++++----------- 9 files changed, 365 insertions(+), 169 deletions(-) create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/InvalidUserInputException.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/idaustriaclient/IdAustriaAuthPvpConfiguration.java (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java') diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java index 858637e9..ba57b28e 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java @@ -180,4 +180,12 @@ public class Constants { public static final String COUNTRY_CODE_DE = "DE"; public static final String COUNTRY_CODE_IT = "IT"; + + public static final String TRANSITION_TO_CREATE_NEW_ERNB_ENTRY_TASK = "TASK_CreateNewErnpEntryTask"; + public static final String TRANSITION_TO_CREATE_GENERATE_GUI_TASK = "TASK_GenerateGuiTask"; + public static final String TRANSITION_TO_GENERATE_GUI_QUERY_AUSTRIAN_RESIDENCE_TASK = + "Task_GenerateGuiQueryAustrianResidenceTask"; + public static final String TRANSITION_TO_GENERATE_MOBILE_PHONE_SIGNATURE_REQUEST_TASK = + "TASK_GenerateMobilePhoneSignatureRequestTask"; + public static final String TRANSITION_TO_GENERATE_EIDAS_LOGIN = "TASK_TODO"; } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/InvalidUserInputException.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/InvalidUserInputException.java new file mode 100644 index 00000000..f28d8afa --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/InvalidUserInputException.java @@ -0,0 +1,33 @@ +/* + * Copyright 2020 A-SIT Plus GmbH + * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ, + * A-SIT Plus GmbH, A-SIT, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "License"); + * You may not use this work except in compliance with the License. + * You may obtain a copy of the License at: + * https://joinup.ec.europa.eu/news/understanding-eupl-v12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * 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.asitplus.eidas.specific.modules.auth.eidas.v2.exception; + +public class InvalidUserInputException extends EidasSAuthenticationException { + private static final long serialVersionUID = 1L; + + public InvalidUserInputException() { + super("eidas.10", null); + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/idaustriaclient/IdAustriaAuthPvpConfiguration.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/idaustriaclient/IdAustriaAuthPvpConfiguration.java new file mode 100644 index 00000000..30c8b65f --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/idaustriaclient/IdAustriaAuthPvpConfiguration.java @@ -0,0 +1,121 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient; + +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.modules.pvp2.api.IPvp2BasicConfiguration; +import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils; +import org.apache.commons.lang3.StringUtils; +import org.opensaml.saml.saml2.metadata.ContactPerson; +import org.opensaml.saml.saml2.metadata.ContactPersonTypeEnumeration; +import org.opensaml.saml.saml2.metadata.EmailAddress; +import org.opensaml.saml.saml2.metadata.GivenName; +import org.opensaml.saml.saml2.metadata.Organization; +import org.opensaml.saml.saml2.metadata.OrganizationDisplayName; +import org.opensaml.saml.saml2.metadata.OrganizationName; +import org.opensaml.saml.saml2.metadata.OrganizationURL; +import org.opensaml.saml.saml2.metadata.SurName; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Arrays; +import java.util.List; + +public class IdAustriaAuthPvpConfiguration implements IPvp2BasicConfiguration { + + private static final String DEFAULT_XML_LANG = "en"; + + @Autowired + private IConfiguration basicConfig; + + @Override + public String getIdpEntityId(String authUrl) throws EaafException { + return authUrl + IdAustriaClientAuthConstants.ENDPOINT_METADATA; + + } + + @Override + public String getIdpSsoPostService(String authUrl) throws EaafException { + return null; + + } + + @Override + public String getIdpSsoRedirectService(String authUrl) throws EaafException { + return null; + + } + + @Override + public String getIdpSsoSoapService(String extractAuthUrlFromRequest) throws EaafException { + return null; + + } + + @Override + public List getIdpContacts() throws EaafException { + final ContactPerson contactPerson = Saml2Utils.createSamlObject(ContactPerson.class); + final GivenName givenName = Saml2Utils.createSamlObject(GivenName.class); + final SurName surname = Saml2Utils.createSamlObject(SurName.class); + final EmailAddress emailAddress = Saml2Utils.createSamlObject(EmailAddress.class); + + givenName.setName(getAndVerifyFromConfiguration( + IdAustriaClientAuthConstants.CONFIG_PROPS_METADATA_CONTACT_GIVENNAME)); + surname.setName(getAndVerifyFromConfiguration( + IdAustriaClientAuthConstants.CONFIG_PROPS_METADATA_CONTACT_SURNAME)); + emailAddress.setAddress(getAndVerifyFromConfiguration( + IdAustriaClientAuthConstants.CONFIG_PROPS_METADATA_CONTACT_EMAIL)); + + contactPerson.setType(ContactPersonTypeEnumeration.TECHNICAL); + contactPerson.setGivenName(givenName); + contactPerson.setSurName(surname); + contactPerson.getEmailAddresses().add(emailAddress); + + return Arrays.asList(contactPerson); + + } + + @Override + public Organization getIdpOrganisation() throws EaafException { + final Organization organisation = Saml2Utils.createSamlObject(Organization.class); + final OrganizationName orgName = Saml2Utils.createSamlObject(OrganizationName.class); + final OrganizationDisplayName orgDisplayName = Saml2Utils.createSamlObject(OrganizationDisplayName.class); + final OrganizationURL orgUrl = Saml2Utils.createSamlObject(OrganizationURL.class); + + orgName.setXMLLang(DEFAULT_XML_LANG); + orgName.setValue(getAndVerifyFromConfiguration( + IdAustriaClientAuthConstants.CONFIG_PROPS_METADATA_ORGANISATION_NAME)); + + orgDisplayName.setXMLLang(DEFAULT_XML_LANG); + orgDisplayName.setValue(getAndVerifyFromConfiguration( + IdAustriaClientAuthConstants.CONFIG_PROPS_METADATA_ORGANISATION_FRIENDLYNAME)); + + orgUrl.setXMLLang(DEFAULT_XML_LANG); + orgUrl.setValue(getAndVerifyFromConfiguration( + IdAustriaClientAuthConstants.CONFIG_PROPS_METADATA_ORGANISATION_URL)); + + + organisation.getOrganizationNames().add(orgName); + organisation.getDisplayNames().add(orgDisplayName); + organisation.getURLs().add(orgUrl); + + return organisation; + } + + + @Override + public IConfiguration getBasicConfiguration() { + return basicConfig; + + } + + private String getAndVerifyFromConfiguration(String configKey) throws EaafConfigurationException { + final String value = basicConfig.getBasicConfiguration(configKey); + if (StringUtils.isEmpty(value)) { + throw new EaafConfigurationException("module.eidasauth.00", + new Object[]{configKey}); + + } + + return value; + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/idaustriaclient/IdAustriaClientAuthCredentialProvider.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/idaustriaclient/IdAustriaClientAuthCredentialProvider.java index 69386194..2608cad1 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/idaustriaclient/IdAustriaClientAuthCredentialProvider.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/idaustriaclient/IdAustriaClientAuthCredentialProvider.java @@ -19,7 +19,7 @@ public class IdAustriaClientAuthCredentialProvider extends AbstractCredentialPro @Autowired IConfiguration authConfig; - private static final String FRIENDLYNAME = "eIDAS centrial authentication"; + private static final String FRIENDLYNAME = "ID Austria authentication"; @Override public KeyStoreConfiguration getBasicKeyStoreConfig() throws EaafConfigurationException { diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateMobilePhoneSignatureRequestTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateMobilePhoneSignatureRequestTask.java index 546a2039..af1ef6f7 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateMobilePhoneSignatureRequestTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateMobilePhoneSignatureRequestTask.java @@ -82,9 +82,6 @@ public class GenerateMobilePhoneSignatureRequestTask extends AbstractAuthServlet log.trace("Starting GenerateMobilePhoneSignatureRequestTask"); //step 15a - //final IAhSpConfiguration spConfig = pendingReq.getServiceProviderConfiguration( - // IAhSpConfiguration.class); - // get entityID for ms-specific eIDAS node final String msNodeEntityID = "TODO"; diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java index 99da21a1..2e754e14 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java @@ -207,13 +207,13 @@ public class InitialSearchTask extends AbstractAuthServletTask { MergedRegisterSearchResult mdsSearchResult = new MergedRegisterSearchResult(resultsZmr, resultsErnp); if (mdsSearchResult.getResultCount() == 0) { - executionContext.put("TASK_CreateNewErnpEntryTask", true); + executionContext.put(Constants.TRANSITION_TO_CREATE_NEW_ERNB_ENTRY_TASK, true); } else { - executionContext.put("TASK_GenerateGuiTask", true); + executionContext.put(Constants.TRANSITION_TO_CREATE_GENERATE_GUI_TASK, true); } //TODO implement next phase and return correct value - return "TODO-Temporary-Endnode-105"; + return null; } private MergedRegisterSearchResult searchInZmrAndErnp(String personIdentifier) { diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveGuiAustrianResidenceResponseTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveGuiAustrianResidenceResponseTask.java index 34fbf507..977262bb 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveGuiAustrianResidenceResponseTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveGuiAustrianResidenceResponseTask.java @@ -23,7 +23,9 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SelectedLoginMethod; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.InvalidUserInputException; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.zmr.IZmrClient; import at.gv.egiz.eaaf.core.api.data.EaafConstants; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; @@ -46,33 +48,70 @@ import java.util.Enumeration; @Component("ReceiveGuiAustrianResidenceResponseTask") public class ReceiveGuiAustrianResidenceResponseTask extends AbstractAuthServletTask { - final String loginMethod = "loginSelection"; + final String formerResidenceAvailableParameterName = "formerResidenceAvailable"; + final String streetParameterName = "street"; + final String zipCodeParameterName = "zipcode"; + final String cityParameterName = "city"; + private final IZmrClient zmrClient; + + public ReceiveGuiAustrianResidenceResponseTask(IZmrClient zmrClient) { + this.zmrClient = zmrClient; + } //TODO @Override public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) throws TaskExecutionException { - try { - log.trace("Starting ReceiveGuiAustrianResidenceResponseTask"); - // set parameter execution context - final Enumeration reqParamNames = request.getParameterNames(); - while (reqParamNames.hasMoreElements()) { - final String paramName = reqParamNames.nextElement(); - if (StringUtils.isNotEmpty(paramName) - && !EaafConstants.PROCESS_ENGINE_PENDINGREQUESTID.equalsIgnoreCase(paramName) - && loginMethod.equalsIgnoreCase(paramName)) { - String value = StringEscapeUtils.escapeHtml(request.getParameter(paramName)); - SelectedLoginMethod selection = SelectedLoginMethod.valueOf(value); - executionContext.put(loginMethod, selection); - - } + log.trace("Starting ReceiveGuiAustrianResidenceResponseTask"); + // set parameter execution context + final Enumeration reqParamNames = request.getParameterNames(); + String street = null; + String city = null; + String zipcode = null; + Boolean formerResidenceAvailable = false; + while (reqParamNames.hasMoreElements()) { + final String paramName = reqParamNames.nextElement(); + if (StringUtils.isNotEmpty(paramName) + && !EaafConstants.PROCESS_ENGINE_PENDINGREQUESTID.equalsIgnoreCase(paramName) + && formerResidenceAvailableParameterName.equalsIgnoreCase(paramName)) { + formerResidenceAvailable = + Boolean.parseBoolean(StringEscapeUtils.escapeHtml(request.getParameter(paramName))); + } + if (StringUtils.isNotEmpty(paramName) + && !EaafConstants.PROCESS_ENGINE_PENDINGREQUESTID.equalsIgnoreCase(paramName) + && streetParameterName.equalsIgnoreCase(paramName)) { + street = StringEscapeUtils.escapeHtml(request.getParameter(paramName)); + } + if (StringUtils.isNotEmpty(paramName) + && !EaafConstants.PROCESS_ENGINE_PENDINGREQUESTID.equalsIgnoreCase(paramName) + && cityParameterName.equalsIgnoreCase(paramName)) { + city = StringEscapeUtils.escapeHtml(request.getParameter(paramName)); + } + if (StringUtils.isNotEmpty(paramName) + && !EaafConstants.PROCESS_ENGINE_PENDINGREQUESTID.equalsIgnoreCase(paramName) + && zipCodeParameterName.equalsIgnoreCase(paramName)) { + zipcode = StringEscapeUtils.escapeHtml(request.getParameter(paramName)); } - - } catch (final Exception e) { - log.error("Parsing selected login method FAILED.", e); - throw new TaskExecutionException(pendingReq, "Parsing selected login method FAILED.", e); } + if (formerResidenceAvailable) { + //step 18 + if (street.isEmpty() || city.isEmpty() || zipcode.isEmpty()) { + //form should ensure that mandatory fields are field => + //this can never happen, expect somebody manipulated the response + throw new TaskExecutionException(pendingReq, "Invalid user input", new InvalidUserInputException()); + } + step18_RegisterSearch(street, city, zipcode);//TODO also MDS? + } else { + //step 20 or for now (phase 1) step 9 + executionContext.put(Constants.TRANSITION_TO_CREATE_NEW_ERNB_ENTRY_TASK, true); + } + + + } + + private void step18_RegisterSearch(String street, String city, String zipcode) { + System.out.println(street + city + zipcode + zmrClient);//TODO } } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveGuiResponseTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveGuiResponseTask.java index fa787792..f8f22ce2 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveGuiResponseTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveGuiResponseTask.java @@ -23,7 +23,9 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SelectedLoginMethod; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.InvalidUserInputException; import at.gv.egiz.eaaf.core.api.data.EaafConstants; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; @@ -62,7 +64,19 @@ public class ReceiveGuiResponseTask extends AbstractAuthServletTask { String value = StringEscapeUtils.escapeHtml(request.getParameter(paramName)); SelectedLoginMethod selection = SelectedLoginMethod.valueOf(value); executionContext.put(loginMethod, selection); - + switch (selection) { + case EIDAS_LOGIN: + executionContext.put(Constants.TRANSITION_TO_GENERATE_EIDAS_LOGIN, true); + break; + case MOBILE_PHONE_SIGNATURE_LOGIN: + executionContext.put(Constants.TRANSITION_TO_GENERATE_MOBILE_PHONE_SIGNATURE_REQUEST_TASK, true); + break; + case NO_OTHER_LOGIN: + executionContext.put(Constants.TRANSITION_TO_GENERATE_GUI_QUERY_AUSTRIAN_RESIDENCE_TASK, true); + break; + default: + throw new InvalidUserInputException(); + } } } } catch (final Exception e) { diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask.java index 9d30b581..8b58f2e1 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask.java @@ -35,14 +35,13 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.IdAustri import at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.IdAustriaClientAuthMetadataProvider; import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.Utils; import at.asitplus.eidas.specific.modules.auth.eidas.v2.zmr.IZmrClient; -import at.gv.egiz.eaaf.core.api.data.ExtendedPvpAttributeDefinitions; +import at.gv.egiz.eaaf.core.api.data.PvpAttributeDefinitions; import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; import at.gv.egiz.eaaf.core.exceptions.EaafBuilderException; import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; import at.gv.egiz.eaaf.core.impl.data.Pair; import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper; import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; -import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl; import at.gv.egiz.eaaf.modules.pvp2.api.binding.IDecoder; import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException; import at.gv.egiz.eaaf.modules.pvp2.exception.SamlAssertionValidationExeption; @@ -68,12 +67,13 @@ import org.opensaml.saml.saml2.metadata.IDPSSODescriptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import javax.naming.ConfigurationException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.transform.TransformerException; import java.io.IOException; +import java.util.HashMap; import java.util.List; +import java.util.Set; /** * Task that searches ErnB and ZMR before adding person to SZR. @@ -132,140 +132,120 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask extends InboundMessage msg = null; - try { + IDecoder decoder = null; + EaafUriCompare comperator = null; + // select Response Binding + if (request.getMethod().equalsIgnoreCase("POST")) { + decoder = new PostBinding(); + comperator = new EaafUriCompare(pendingReq.getAuthUrl() + IdAustriaClientAuthConstants.ENDPOINT_POST); + log.trace("Receive PVP Response from 'ID Austria node', by using POST-Binding."); - IDecoder decoder = null; - EaafUriCompare comperator = null; - // select Response Binding - if (request.getMethod().equalsIgnoreCase("POST")) { - decoder = new PostBinding(); - comperator = new EaafUriCompare(pendingReq.getAuthUrl() + IdAustriaClientAuthConstants.ENDPOINT_POST); - log.trace("Receive PVP Response from 'ID Austria node', by using POST-Binding."); + } else if (request.getMethod().equalsIgnoreCase("GET")) { + decoder = new RedirectBinding(); + comperator = new EaafUriCompare(pendingReq.getAuthUrl() + + IdAustriaClientAuthConstants.ENDPOINT_REDIRECT); + log.trace("Receive PVP Response from 'ID Austria node', by using Redirect-Binding."); - } else if (request.getMethod().equalsIgnoreCase("GET")) { - decoder = new RedirectBinding(); - comperator = new EaafUriCompare(pendingReq.getAuthUrl() - + IdAustriaClientAuthConstants.ENDPOINT_REDIRECT); - log.trace("Receive PVP Response from 'ID Austria node', by using Redirect-Binding."); - - } else { - log.warn("Receive PVP Response, but Binding (" - + request.getMethod() + ") is not supported."); - throw new AuthnResponseValidationException(ERROR_PVP_03, new Object[]{ - IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING}); - - } - - // decode PVP response object - msg = (InboundMessage) decoder.decode( - request, response, metadataProvider, IDPSSODescriptor.DEFAULT_ELEMENT_NAME, - comperator); - - // validate response signature - if (!msg.isVerified()) { - samlVerificationEngine.verify(msg, TrustEngineFactory.getSignatureKnownKeysTrustEngine( - metadataProvider)); - msg.setVerified(true); - - } - - // validate assertion - final Pair processedMsg = - preProcessAuthResponse((PvpSProfileResponse) msg); - - //check if SAML2 response contains user-stop decision - if (processedMsg.getSecond()) { - stopProcessFromUserDecision(executionContext, request, response); - - } else { - // validate entityId of response - final String msNodeEntityID = authConfig.getBasicConfiguration( - IdAustriaClientAuthConstants.CONFIG_PROPS_NODE_ENTITYID); - final String respEntityId = msg.getEntityID(); - if (!msNodeEntityID.equals(respEntityId)) { - log.warn("Response Issuer is not a 'ms-specific eIDAS node'. Stopping eIDAS authentication ..."); - throw new AuthnResponseValidationException(ERROR_PVP_08, - new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING, - msg.getEntityID()}); - - } + } else { + log.warn("Receive PVP Response, but Binding (" + + request.getMethod() + ") is not supported."); + throw new AuthnResponseValidationException(ERROR_PVP_03, new Object[]{ + IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING}); - // initialize Attribute extractor - final AssertionAttributeExtractor extractor = - new AssertionAttributeExtractor(processedMsg.getFirst().getResponse()); + } - getAuthDataFromInterfederation(extractor); + // decode PVP response object + msg = (InboundMessage) decoder.decode( + request, response, metadataProvider, IDPSSODescriptor.DEFAULT_ELEMENT_NAME, + comperator); - // set NeedConsent to false, because user gives consont during authentication - pendingReq.setNeedUserConsent(false); + // validate response signature + if (!msg.isVerified()) { + samlVerificationEngine.verify(msg, TrustEngineFactory.getSignatureKnownKeysTrustEngine( + metadataProvider)); + msg.setVerified(true); - // store pending-request - requestStoreage.storePendingRequest(pendingReq); + } - //set E-ID process flag to execution context - // final AhAuthProcessDataWrapper session = pendingReq.getSessionData( - // AhAuthProcessDataWrapper.class); - // executionContext.put(AuthHandlerConstants.PROCESSCONTEXT_WAS_EID_PROCESS, session.isEidProcess()); - // executionContext.put(AuthHandlerConstants.HTTP_PARAM_USE_MANDATES, session.isMandateUsed()); + // validate assertion + final Pair processedMsg = + preProcessAuthResponse((PvpSProfileResponse) msg); + //check if SAML2 response contains user-stop decision + if (processedMsg.getSecond()) { + stopProcessFromUserDecision(executionContext, request, response); - log.info("Receive a valid assertion from IDP " + msg.getEntityID()); + } else { + // validate entityId of response + final String msNodeEntityID = authConfig.getBasicConfiguration( + IdAustriaClientAuthConstants.CONFIG_PROPS_NODE_ENTITYID); + final String respEntityId = msg.getEntityID(); + if (!msNodeEntityID.equals(respEntityId)) { + log.warn("Response Issuer is not a 'ID Austria node'. Stopping eIDAS authentication ..."); + throw new AuthnResponseValidationException(ERROR_PVP_08, + new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING, + msg.getEntityID()}); } - } catch (final AuthnResponseValidationException e) { - throw new TaskExecutionException(pendingReq, ERROR_MSG_03, e); - - } catch (MessageDecodingException | SecurityException | SamlSigningException e) { - //final String samlRequest = request.getParameter("SAMLRequest"); - //log.debug("Receive INVALID PVP Response from 'ms-specific eIDAS node': {}", - // samlRequest, null, e); - throw new TaskExecutionException(pendingReq, ERROR_MSG_00, - new AuthnResponseValidationException(ERROR_PVP_11, - new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING}, e)); - - } catch (IOException | MarshallingException | TransformerException e) { - log.debug("Processing PVP response from 'ms-specific eIDAS node' FAILED.", e); - throw new TaskExecutionException(pendingReq, ERROR_MSG_01, - new AuthnResponseValidationException(ERROR_PVP_12, - new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING, e.getMessage()}, - e)); - - } catch (final CredentialsNotAvailableException e) { - log.debug("PVP response decrytion FAILED. No credential found.", e); - throw new TaskExecutionException(pendingReq, ERROR_MSG_02, - new AuthnResponseValidationException(ERROR_PVP_10, - new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING}, e)); - - } catch (final Exception e) { - log.debug("PVP response validation FAILED. Msg:" + e.getMessage(), e); - throw new TaskExecutionException(pendingReq, ERROR_MSG_03, - new AuthnResponseValidationException(ERROR_PVP_12, - new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING, e.getMessage()}, e)); + // initialize Attribute extractor + final AssertionAttributeExtractor extractor = + new AssertionAttributeExtractor(processedMsg.getFirst().getResponse()); + + String bpkzp = getAuthDataFromInterfederation(extractor); + + MergedRegisterSearchResult result = searchInZmrAndErnp(bpkzp); + if (result.getResultCount() == 0) { + //go to step 16 + executionContext.put(Constants.TRANSITION_TO_GENERATE_GUI_QUERY_AUSTRIAN_RESIDENCE_TASK, true); + return; + } else if (result.getResultCount() == 1) { + String bpk = + Utils.step7aKittProcess(ernpClient, zmrClient, initialSearchResult, result, eidData, pendingReq); + authProcessData.setGenericDataToSession(Constants.DATA_RESULT_MATCHING_BPK, bpk); + //node 110 + } else if (result.getResultCount() > 1) { + throw new ManualFixNecessaryException("bpkzp:" + bpkzp);// node 108 + } - } + // set NeedConsent to false, because user gives consont during authentication + pendingReq.setNeedUserConsent(false); + log.info("Receive a valid assertion from IDP " + msg.getEntityID()); - //TODO extract bPK-ZP from response - String bpkzp = "TODO"; - MergedRegisterSearchResult result = searchInZmrAndErnp(bpkzp); - if (result.getResultCount() == 0) { - //go to step 16 - //TODO set context variable - return; - } else if (result.getResultCount() == 1) { - String bpk = Utils.step7aKittProcess(ernpClient, zmrClient, initialSearchResult, result, eidData, pendingReq); - authProcessData.setGenericDataToSession(Constants.DATA_RESULT_MATCHING_BPK, bpk); - //node 110 - //TODO bpk vs bpkzp???? same? - } else if (result.getResultCount() > 1) { - throw new ManualFixNecessaryException("bpkzp:" + bpkzp);// node 108 } + } catch (final AuthnResponseValidationException e) { + throw new TaskExecutionException(pendingReq, ERROR_MSG_03, e); + + } catch (MessageDecodingException | SecurityException | SamlSigningException e) { + //final String samlRequest = request.getParameter("SAMLRequest"); + //log.debug("Receive INVALID PVP Response from 'ms-specific eIDAS node': {}", + // samlRequest, null, e); + throw new TaskExecutionException(pendingReq, ERROR_MSG_00, + new AuthnResponseValidationException(ERROR_PVP_11, + new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING}, e)); + + } catch (IOException | MarshallingException | TransformerException e) { + log.debug("Processing PVP response from 'ms-specific eIDAS node' FAILED.", e); + throw new TaskExecutionException(pendingReq, ERROR_MSG_01, + new AuthnResponseValidationException(ERROR_PVP_12, + new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING, e.getMessage()}, + e)); + + } catch (final CredentialsNotAvailableException e) { + log.debug("PVP response decrytion FAILED. No credential found.", e); + throw new TaskExecutionException(pendingReq, ERROR_MSG_02, + new AuthnResponseValidationException(ERROR_PVP_10, + new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING}, e)); + } catch (final Exception e) { - log.error("Initial search FAILED.", e); - throw new TaskExecutionException(pendingReq, "Initial search FAILED.", e); + log.debug("PVP response validation FAILED. Msg:" + e.getMessage(), e); + throw new TaskExecutionException(pendingReq, ERROR_MSG_03, + new AuthnResponseValidationException(ERROR_PVP_12, + new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING, e.getMessage()}, e)); } + } private Pair preProcessAuthResponse(PvpSProfileResponse msg) @@ -325,44 +305,47 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask extends return null; } - private void getAuthDataFromInterfederation(AssertionAttributeExtractor extractor) - throws EaafBuilderException, ConfigurationException { + private String getAuthDataFromInterfederation(AssertionAttributeExtractor extractor) + throws EaafBuilderException { List requiredEidasNodeAttributes = IdAustriaClientAuthConstants.DEFAULT_REQUIRED_PVP_ATTRIBUTE_NAMES; - + String bpk = null; try { // check if all attributes are include if (!extractor.containsAllRequiredAttributes() || !extractor.containsAllRequiredAttributes( requiredEidasNodeAttributes)) { - log.warn("PVP Response from 'ms-specific eIDAS node' contains not all requested attributes."); + log.warn("PVP Response from 'ID Austria node' contains not all requested attributes."); throw new AssertionValidationExeption(ERROR_PVP_06, new Object[]{ IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING}); } - // copy attributes into MOASession - // final AhAuthProcessDataWrapper session = pendingReq.getSessionData( - // AhAuthProcessDataWrapper.class); - // final Set includedAttrNames = extractor.getAllIncludeAttributeNames(); - // for (final String attrName : includedAttrNames) { - // injectAuthInfosIntoSession(session, attrName, - // extractor.getSingleAttributeValue(attrName)); - // - // } - - //set piiTransactionId from eIDAS Connector - String piiTransactionId = extractor.getSingleAttributeValue( - ExtendedPvpAttributeDefinitions.EID_PII_TRANSACTION_ID_NAME); - if (StringUtils.isNotEmpty(piiTransactionId) && pendingReq instanceof RequestImpl) { - log.info("Receive piiTransactionId from Austrian eIDAS Connector. Use this for further processing"); - ((RequestImpl) pendingReq).setUniquePiiTransactionIdentifier(piiTransactionId); + HashMap map = new HashMap<>(); + final Set includedAttrNames = extractor.getAllIncludeAttributeNames(); + for (final String attrName : includedAttrNames) { + map.put(attrName, extractor.getSingleAttributeValue(attrName)); - } else { - log.debug("Receive no piiTransactionId from Austrian eIDAS Connector."); + if (PvpAttributeDefinitions.BPK_NAME.equals(attrName)) { + bpk = extractor.getSingleAttributeValue(attrName); + } + //injectAuthInfosIntoSession(session, attrName, + // extractor.getSingleAttributeValue(attrName)); } + //set piiTransactionId from eIDAS Connector + // String piiTransactionId = extractor.getSingleAttributeValue( + // ExtendedPvpAttributeDefinitions.EID_PII_TRANSACTION_ID_NAME); + // if (StringUtils.isNotEmpty(piiTransactionId) && pendingReq instanceof RequestImpl) { + // log.info("Receive piiTransactionId from Austrian eIDAS Connector. Use this for further processing"); + // ((RequestImpl) pendingReq).setUniquePiiTransactionIdentifier(piiTransactionId); + // + // } else { + // log.debug("Receive no piiTransactionId from Austrian eIDAS Connector."); + // + // } + // set foreigner flag // session.setForeigner(true); @@ -383,6 +366,7 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask extends throw new EaafBuilderException(ERROR_PVP_06, null, e.getMessage(), e); } + return bpk; } // private void injectAuthInfosIntoSession(AhAuthProcessDataWrapper session, String attrName, String attrValue) @@ -404,7 +388,7 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask extends // } else if (PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME.equals(attrName)) { // session.setQaaLevel(attrValue); // - // // } else if (ExtendedPvpAttributeDefinitions.EID_MIS_MANDATE_NAME.equals(attrName) + // // } else if (ExtendedPvpAttributeDefinitions.EID_MIS_MANDATE_NAME.equals(attrName) // // && authConfig.getBasicConfigurationBoolean( // // IdAustriaClientAuthConstants.CONFIG_PROPS_SEMPER_MANDATES_ACTIVE, false)) { // // session.setMandateDate(new SignedMandateDao(attrValue)); -- cgit v1.2.3