From 6d09f43225ba2e0f6d7b0583f843c858a1015807 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Thu, 26 Jul 2018 10:30:14 +0200 Subject: namespace refactoring --- .../modules/authmodule_eIDASv2/Constants.java | 110 ++++++ .../eIDASAuthenticationModulImpl.java | 53 +++ .../eIDASAuthenticationSpringResourceProvider.java | 30 ++ .../authmodule_eIDASv2/eIDASSignalServlet.java | 131 +++++++ .../exception/SZRCommunicationException.java | 15 + .../exception/eIDASAttributeException.java | 15 + .../exception/eIDASAuthenticationException.java | 20 ++ .../exception/eIDASValidationException.java | 14 + .../service/eIDASAttributeRegistry.java | 115 +++++++ .../modules/authmodule_eIDASv2/szr/SZRClient.java | 372 ++++++++++++++++++++ .../modules/authmodule_eIDASv2/szr/SZRService.java | 139 ++++++++ .../tasks/CreateIdentityLinkTask.java | 380 +++++++++++++++++++++ .../tasks/GenerateAuthnRequestTask.java | 306 +++++++++++++++++ .../tasks/ReceiveAuthnResponseTask.java | 97 ++++++ .../authmodule_eIDASv2/utils/LoggingHandler.java | 52 +++ .../utils/eIDASResponseUtils.java | 98 ++++++ .../validator/eIDASResponseValidator.java | 135 ++++++++ .../modules/authmodule_eIDASv2/Constants.java | 110 ------ .../eIDASAuthenticationModulImpl.java | 53 --- .../eIDASAuthenticationSpringResourceProvider.java | 30 -- .../authmodule_eIDASv2/eIDASSignalServlet.java | 131 ------- .../exception/SZRCommunicationException.java | 15 - .../exception/eIDASAttributeException.java | 15 - .../exception/eIDASAuthenticationException.java | 20 -- .../exception/eIDASValidationException.java | 14 - .../service/eIDASAttributeRegistry.java | 115 ------- .../modules/authmodule_eIDASv2/szr/SZRClient.java | 372 -------------------- .../modules/authmodule_eIDASv2/szr/SZRService.java | 139 -------- .../tasks/CreateIdentityLinkTask.java | 380 --------------------- .../tasks/GenerateAuthnRequestTask.java | 306 ----------------- .../tasks/ReceiveAuthnResponseTask.java | 97 ------ .../authmodule_eIDASv2/utils/LoggingHandler.java | 52 --- .../utils/eIDASResponseUtils.java | 98 ------ .../validator/eIDASResponseValidator.java | 135 -------- 34 files changed, 2082 insertions(+), 2082 deletions(-) create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/Constants.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationModulImpl.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationSpringResourceProvider.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/eIDASSignalServlet.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/SZRCommunicationException.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAttributeException.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAuthenticationException.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASValidationException.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/eIDASAttributeRegistry.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/szr/SZRClient.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/szr/SZRService.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/ReceiveAuthnResponseTask.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/utils/LoggingHandler.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/utils/eIDASResponseUtils.java create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/Constants.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationModulImpl.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationSpringResourceProvider.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASSignalServlet.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/SZRCommunicationException.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAttributeException.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAuthenticationException.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASValidationException.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/service/eIDASAttributeRegistry.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/szr/SZRClient.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/szr/SZRService.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/ReceiveAuthnResponseTask.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/utils/LoggingHandler.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/utils/eIDASResponseUtils.java delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java (limited to 'eidas_modules/authmodule-eIDAS-v2/src/main/java/at') diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/Constants.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/Constants.java new file mode 100644 index 00000000..64cf6af2 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/Constants.java @@ -0,0 +1,110 @@ +/******************************************************************************* + *******************************************************************************/ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import at.gv.egiz.eaaf.core.api.data.EAAFConstants; + +public class Constants { + + public static final String DATA_REQUESTERID = "req_requesterId"; + public static final String DATA_PROVIDERNAME = "req_providerName"; + public static final String DATA_REQUESTED_LOA_LIST = "req_requestedLoA"; + public static final String DATA_REQUESTED_LOA_COMPERISON = "req_requestedLoAComperision"; + public static final String DATA_FULL_EIDAS_RESPONSE = "resp_fulleIDASResponse"; + + + //templates for post-binding forwarding + public static final String TEMPLATE_POST_FORWARD_NAME = "eidas_node_forward.html"; + public static final String TEMPLATE_POST_FORWARD_ENDPOINT = "endPoint"; + public static final String TEMPLATE_POST_FORWARD_TOKEN_NAME = "tokenName"; + public static final String TEMPLATE_POST_FORWARD_TOKEN_VALUE = "tokenValue"; + + + //configuration properties + public static final String CONIG_PROPS_EIDAS_PREFIX="auth.eIDAS"; + public static final String CONIG_PROPS_EIDAS_NODE= CONIG_PROPS_EIDAS_PREFIX + ".node_v2"; + public static final String CONIG_PROPS_EIDAS_NODE_COUNTRYCODE = CONIG_PROPS_EIDAS_NODE + ".countrycode"; + public static final String CONIG_PROPS_EIDAS_NODE_PUBLICSECTOR_TARGETS = CONIG_PROPS_EIDAS_NODE + ".publicSectorTargets"; + public static final String CONIG_PROPS_EIDAS_NODE_ENTITYID = CONIG_PROPS_EIDAS_NODE + ".entityId"; + public static final String CONIG_PROPS_EIDAS_NODE_FORWARD_URL = CONIG_PROPS_EIDAS_NODE + ".forward.endpoint"; + public static final String CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD = CONIG_PROPS_EIDAS_NODE + ".forward.method"; + public static final String CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_ONLYNATURAL = CONIG_PROPS_EIDAS_NODE + ".attributes.requested.onlynatural."; + public static final String CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_REPRESENTATION = CONIG_PROPS_EIDAS_NODE + ".attributes.requested.representation."; + public static final String CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME = CONIG_PROPS_EIDAS_NODE + ".workarounds.addAlwaysProviderName";; + public static final String CONIG_PROPS_EIDAS_NODE_WORKAROUND_USEREQUESTIDASTRANSACTIONIDENTIFIER = CONIG_PROPS_EIDAS_NODE + ".workarounds.useRequestIdAsTransactionIdentifier"; + + public static final String FORWARD_METHOD_POST = "POST"; + public static final String FORWARD_METHOD_GET = "GET"; + + public static final String CONIG_PROPS_EIDAS_SZRCLIENT= CONIG_PROPS_EIDAS_PREFIX + ".szrclient"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_USETESTSERVICE= CONIG_PROPS_EIDAS_SZRCLIENT + ".useTestService"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_TRACEMESSAGES= CONIG_PROPS_EIDAS_SZRCLIENT + ".debug.logfullmessages"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_USEDUMMY= CONIG_PROPS_EIDAS_SZRCLIENT + ".debug.useDummySolution"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_INSERTERNB= CONIG_PROPS_EIDAS_SZRCLIENT + ".debug.insertERnB"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_TIMEOUT_CONNECTION= CONIG_PROPS_EIDAS_SZRCLIENT + ".timeout.connection"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_TIMEOUT_RESPONSE= CONIG_PROPS_EIDAS_SZRCLIENT + ".timeout.response"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_ENDPOINT_PROD= CONIG_PROPS_EIDAS_SZRCLIENT + ".endpoint.prod"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_ENDPOINT_TEST= CONIG_PROPS_EIDAS_SZRCLIENT + ".endpoint.test"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_SSL_KEYSTORE_PATH = CONIG_PROPS_EIDAS_SZRCLIENT + ".ssl.keyStore.path"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_SSL_KEYSTORE_PASSWORD = CONIG_PROPS_EIDAS_SZRCLIENT + ".ssl.keyStore.password"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_SSL_TRUSTSTORE_PATH = CONIG_PROPS_EIDAS_SZRCLIENT + ".ssl.trustStore.path"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_SSL_TRUSTSTORE_PASSWORD = CONIG_PROPS_EIDAS_SZRCLIENT + ".ssl.trustStore.password"; + + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_EDOCUMENTTYPE = CONIG_PROPS_EIDAS_SZRCLIENT + ".params.documenttype"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_VKZ = CONIG_PROPS_EIDAS_SZRCLIENT + ".params.vkz"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_ISSUING_DATE = CONIG_PROPS_EIDAS_SZRCLIENT + ".params.issuingdate"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_ISSUING_AUTHORITY = CONIG_PROPS_EIDAS_SZRCLIENT + ".params.issuingauthority"; + public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_KEYS_USEDUMMY= CONIG_PROPS_EIDAS_SZRCLIENT + ".params.usedummykeys"; + + //http endpoint descriptions + public static final String eIDAS_HTTP_ENDPOINT_SP_POST = "/eidas/light/sp/post"; + public static final String eIDAS_HTTP_ENDPOINT_SP_REDIRECT = "/eidas/light/sp/redirect"; + public static final String eIDAS_HTTP_ENDPOINT_IDP_COLLEAGUEREQUEST = "/eidas/light/ColleagueRequest"; + public static final String eIDAS_HTTP_ENDPOINT_METADATA = "/eidas/light/metadata"; + + //eIDAS request parameters + public static final String eIDAS_REQ_NAMEID_FORMAT = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"; + + //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 = "FirstName"; + public static final String eIDAS_ATTR_CURRENTFAMILYNAME = "FamilyName"; + public static final String eIDAS_ATTR_LEGALPERSONIDENTIFIER = "LegalPersonIdentifier"; + public static final String eIDAS_ATTR_LEGALNAME = "LegalName"; + + public static final List NATURALPERSONMINIMUMDATASETLIST = Collections.unmodifiableList(new ArrayList() { + private static final long serialVersionUID = 1L; + { + //TODO: find correct location of attribute definitions +// add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.CURRENT_FAMILY_NAME.getNameUri()); +// add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.CURRENT_GIVEN_NAME.getNameUri()); +// add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.DATE_OF_BIRTH.getNameUri()); +// add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.PERSON_IDENTIFIER.getNameUri()); + } + }); + + public static final String POLICY_DEFAULT_ALLOWED_TARGETS = + EAAFConstants.URN_PREFIX_CDID.replaceAll("\\.", "\\\\.").replaceAll("\\+", "\\\\+") + ".*"; + + //SAML2 Constants + public static final String SUCCESS_URI = "urn:oasis:names:tc:SAML:2.0:status:Success"; + + public static final String HTTP_CLIENT_DEFAULT_TIMEOUT_CONNECTION = "30"; //seconds + public static final String HTTP_CLIENT_DEFAULT_TIMEOUT_RESPONSE = "60"; //seconds + + + //Default values for SZR communication + public static final String SZR_CONSTANTS_DEFAULT_DOCUMENT_TYPE = "ELEKTR_DOKUMENT"; + + //TODO remove!!! + public static final String SZR_CONSTANTS_DEFAULT_ISSUING_DATE = "2014-01-01"; + public static final String SZR_CONSTANTS_DEFAULT_ISSUING_AUTHORITY = "ms-specific eIDAS-Node for AT"; + public final static byte[] SZR_CONSTANTS_DEFAULT_PUBL_KEY = new byte[] {48, -127, -97, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0, 3, -127, -115, 0, 48, -127, -119, 2, -127, -127, 0, -106, 114, -113, -1, -84, 116, 35, 3, 70, -81, 81, -110, -10, -59, 114, 4, -109, 86, 127, -50, 125, 47, 4, 80, 79, 53, 117, -36, 15, -16, -61, 110, 39, 89, 29, -43, 37, -127, 80, -109, -38, 65, 125, -119, 44, -111, -21, 47, -98, 38, -112, -24, 107, -110, 17, -10, 51, -4, -36, -72, -28, -18, -14, 117, -67, 76, -31, 32, 92, 104, -21, 68, 31, -12, 30, -104, -104, 42, -107, 126, 84, 50, 85, -117, 44, -100, -4, 102, -100, 52, -68, 77, -32, 9, -16, -30, -104, -90, 107, -88, 7, 97, -94, 72, -61, -40, 80, -112, -65, -25, -72, -19, -95, -54, 31, 15, 24, -105, 123, -81, 23, -123, 92, -103, -101, 47, 47, -105, 2, 3, 1, 0, 1}; + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationModulImpl.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationModulImpl.java new file mode 100644 index 00000000..39be3fbd --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationModulImpl.java @@ -0,0 +1,53 @@ +/******************************************************************************* + *******************************************************************************/ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2; + +import org.apache.commons.lang3.StringUtils; + +import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; +import at.gv.egiz.eaaf.core.api.idp.auth.modules.AuthModule; +import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; + +/** + * @author tlenz + * + */ +public class eIDASAuthenticationModulImpl implements AuthModule { + + private int priority = 1; + + @Override + public int getPriority() { + return priority; + } + + /** + * Sets the priority of this module. Default value is {@code 0}. + * @param priority The priority. + */ + public void setPriority(int priority) { + this.priority = priority; + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#selectProcess(at.gv.egovernment.moa.id.process.api.ExecutionContext) + */ + @Override + public String selectProcess(ExecutionContext context) { + if (StringUtils.isNotBlank((String) context.get(MSeIDASNodeConstants.REQ_PARAM_SELECTED_COUNTRY)) || + StringUtils.isNotBlank((String) context.get(MSeIDASNodeConstants.REQ_PARAM_SELECTED_COUNTRY))) + return "eIDASAuthentication_v2"; + else + return null; + + } + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getProcessDefinitions() + */ + @Override + public String[] getProcessDefinitions() { + return new String[] { "classpath:eIDAS.Authentication.process.xml" }; + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationSpringResourceProvider.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationSpringResourceProvider.java new file mode 100644 index 00000000..d44ef348 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationSpringResourceProvider.java @@ -0,0 +1,30 @@ +/******************************************************************************* + *******************************************************************************/ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2; + +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import at.gv.egiz.components.spring.api.SpringResourceProvider; + +public class eIDASAuthenticationSpringResourceProvider implements SpringResourceProvider { + + @Override + public String getName() { + return "Auth. module for eIDAS Ref. Impl. v2.x"; + } + + @Override + public String[] getPackagesToScan() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource[] getResourcesToLoad() { + ClassPathResource eIDASAuthConfig = new ClassPathResource("/eidas_v2_auth.beans.xml", eIDASAuthenticationSpringResourceProvider.class); + + return new Resource[] {eIDASAuthConfig}; + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/eIDASSignalServlet.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/eIDASSignalServlet.java new file mode 100644 index 00000000..41e2aa03 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/eIDASSignalServlet.java @@ -0,0 +1,131 @@ +/******************************************************************************* + *******************************************************************************/ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import com.google.common.collect.ImmutableSortedSet; + +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASAuthenticationException; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.service.eIDASAttributeRegistry; +import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractProcessEngineSignalController; +import eu.eidas.auth.commons.EidasParameterKeys; +import eu.eidas.auth.commons.light.ILightResponse; +import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames; +import eu.eidas.specificcommunication.exception.SpecificCommunicationException; +import eu.eidas.specificcommunication.protocol.impl.SpecificConnectorCommunicationServiceImpl; + + +/** + * @author tlenz + * + */ +@Controller +public class eIDASSignalServlet extends AbstractProcessEngineSignalController { + + private static final Logger log = LoggerFactory.getLogger(eIDASSignalServlet.class); + @Autowired private ApplicationContext context; + @Autowired private eIDASAttributeRegistry attrRegistry; + + public eIDASSignalServlet() { + super(); + log.debug("Registering servlet " + getClass().getName() + + " with mappings '"+ Constants.eIDAS_HTTP_ENDPOINT_SP_POST + + "' and '"+ Constants.eIDAS_HTTP_ENDPOINT_SP_REDIRECT + "'."); + + } + + @RequestMapping(value = { Constants.eIDAS_HTTP_ENDPOINT_SP_POST, + Constants.eIDAS_HTTP_ENDPOINT_SP_REDIRECT + }, + method = {RequestMethod.POST, RequestMethod.GET}) + public void restoreEidasAuthProcess(HttpServletRequest req, HttpServletResponse resp) throws IOException { + signalProcessManagement(req, resp); + } + + + /** + * Protocol specific implementation to get the pending-requestID + * from http request object + * + * @param request The http Servlet-Request object + * @return The Pending-request id + * + */ + @Override + public String getPendingRequestId(HttpServletRequest request) { + //String sessionId = super.getPendingRequestId(request); + + try { + //get token from Request + final String tokenBase64 = request.getParameter(EidasParameterKeys.TOKEN.toString()); + if (StringUtils.isEmpty(tokenBase64)) { + log.warn("NO eIDAS message token found."); + throw new eIDASAuthenticationException("eidas.04", null); + + } + log.trace("Receive eIDAS-node token: " + tokenBase64 + " Starting transaction-restore process ... "); + + + + final SpecificConnectorCommunicationServiceImpl specificConnectorCommunicationService = + (SpecificConnectorCommunicationServiceImpl) context.getBean(SpecificCommunicationDefinitionBeanNames.SPECIFIC_CONNECTOR_COMMUNICATION_SERVICE.toString()); + ILightResponse eIDASResponse = specificConnectorCommunicationService.getAndRemoveResponse(tokenBase64, + ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes())); + + String pendingReqId = null; + if (StringUtils.isEmpty(eIDASResponse.getRelayState())) { + log.debug("eIDAS Node returns no RelayState. "); + + if (authConfig.getBasicMOAIDConfigurationBoolean( + Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_USEREQUESTIDASTRANSACTIONIDENTIFIER, + false)) { + log.trace("Use lightRequestId to recover session ... "); + pendingReqId = transactionStorage.get(eIDASResponse.getInResponseToId(), String.class); + if (StringUtils.isNotEmpty(pendingReqId)) { + log.debug("Restoring session with lightRequestId ... "); + transactionStorage.remove(eIDASResponse.getInResponseToId()); + + } + } + + } else { + log.debug("Find transaction identifier in SAML2 'RelayState': " + eIDASResponse.getRelayState()); + pendingReqId = eIDASResponse.getRelayState(); + + } + + if (StringUtils.isNotEmpty(pendingReqId)) { + request.setAttribute(Constants.DATA_FULL_EIDAS_RESPONSE, eIDASResponse); + return pendingReqId; + + } + + log.info("NO transaction identifier found! Stopping process ...."); + log.trace("FullResponse: " + eIDASResponse.toString()); + + } catch (SpecificCommunicationException e) { + log.warn("Can NOT load eIDAS Response from cache.", e); + log.debug("eIDAS response token was: " + request.getParameter(EidasParameterKeys.TOKEN.toString())); + + } catch (Exception e) { + log.warn("Unable to retrieve moa session id.", e); + + } + + return null; + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/SZRCommunicationException.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/SZRCommunicationException.java new file mode 100644 index 00000000..defc03db --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/SZRCommunicationException.java @@ -0,0 +1,15 @@ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception; + +public class SZRCommunicationException extends eIDASAuthenticationException { + + private static final long serialVersionUID = 1L; + + public SZRCommunicationException(String internalMsgId, Object[] params) { + super(internalMsgId, params); + } + + public SZRCommunicationException(String internalMsgId, Object[] params, Throwable e) { + super(internalMsgId, params, e); + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAttributeException.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAttributeException.java new file mode 100644 index 00000000..2ce9fcd7 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAttributeException.java @@ -0,0 +1,15 @@ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception; + +public class eIDASAttributeException extends eIDASAuthenticationException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public eIDASAttributeException(String attrbuteName) { + super("eidas.00", new Object[] {attrbuteName}); + + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAuthenticationException.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAuthenticationException.java new file mode 100644 index 00000000..93298a92 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAuthenticationException.java @@ -0,0 +1,20 @@ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception; + +import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException; + +public class eIDASAuthenticationException extends EAAFAuthenticationException{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + public eIDASAuthenticationException(String internalMsgId, Object[] params) { + super(internalMsgId, params); + } + + public eIDASAuthenticationException(String internalMsgId, Object[] params, Throwable e) { + super(internalMsgId, params, e); + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASValidationException.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASValidationException.java new file mode 100644 index 00000000..2bac7d04 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASValidationException.java @@ -0,0 +1,14 @@ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception; + +public class eIDASValidationException extends eIDASAuthenticationException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public eIDASValidationException(String internalMsgId, Object[] params) { + super(internalMsgId, params); + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/eIDASAttributeRegistry.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/eIDASAttributeRegistry.java new file mode 100644 index 00000000..de9f6455 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/service/eIDASAttributeRegistry.java @@ -0,0 +1,115 @@ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.service; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.Constants; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; +import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; +import eu.eidas.auth.commons.attribute.AttributeRegistries; +import eu.eidas.auth.commons.attribute.AttributeRegistry; + +@Service("attributeRegistry") +public class eIDASAttributeRegistry { + private static final Logger log = LoggerFactory.getLogger(eIDASAttributeRegistry.class); + @Autowired private IConfiguration basicConfig; + + private AttributeRegistry coreAttributeRegistry; + + private String eidasAttributesFile; + private String additionalAttributesFile; + + @PostConstruct + private void initialize() throws RuntimeException { + try { + if (eidasAttributesFile.isEmpty()) { + log.error("Basic eIDAS addribute definition NOT defined"); + throw new EAAFConfigurationException("config.30", + new Object[] {"eidas-attributes.xml"}); + + } + + boolean additionalAttrAvailabe = false; + if (!additionalAttributesFile.isEmpty()) { + File file = new File(additionalAttributesFile); + if (file.exists()) + additionalAttrAvailabe = true; + + } + + if (!additionalAttrAvailabe) { + log.info("Start eIDAS ref. impl. Core without additional eIDAS attribute definitions ... "); + coreAttributeRegistry = AttributeRegistries.fromFiles(eidasAttributesFile, null); + + } else { + //load attribute definitions + log.info("Start eIDAS ref. impl. Core with additional eIDAS attribute definitions ... "); + coreAttributeRegistry = AttributeRegistries.fromFiles(eidasAttributesFile, null, additionalAttributesFile); + + } + + } catch (Throwable e) { + log.error("Can NOT initialize eIDAS attribute definition." , e); + new RuntimeException("Can NOT initialize eIDAS attribute definition.", e); + + } + } + + + public AttributeRegistry getCoreAttributeRegistry() { + return coreAttributeRegistry; + } + + public Map getAttributeSetFromConfiguration() { + Map result = new HashMap(); + + /*TODO: select set for representation if mandates should be used. + * It's an open task in respect to requested eIDAS attributes and isRequired flag, + * because there can be a decision problem in case of natural or legal person representation! + * From an Austrian use-case point of view, an Austrian service provider can support mandates for + * natural and legal persons at the same time. However, we CAN NOT request attributes for natural AND + * legal persons on the same time, because it's not possible to represent both simultaneously. + */ + Map configAttributes = + basicConfig.getBasicMOAIDConfigurationWithPrefix( + Constants.CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_ONLYNATURAL); + for (String el: configAttributes.values()) { + if (StringUtils.isNotEmpty(el.trim())) { + List attrDef = KeyValueUtils.getListOfCSVValues(el.trim()); + boolean isRequired = false; + if (attrDef.size() == 2) + isRequired = Boolean.parseBoolean(attrDef.get(1)); + + result.put(attrDef.get(0), isRequired); + + } + } + + log.trace("Load #" + result.size() + " requested attributes from configuration"); + return result; + + } + + + public void setEidasAttributesFile(String eidasAttributesFile) { + this.eidasAttributesFile = eidasAttributesFile; + } + + public void setAdditionalAttributesFile(String additionalAttributesFile) { + this.additionalAttributesFile = additionalAttributesFile; + } + + +} + diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/szr/SZRClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/szr/SZRClient.java new file mode 100644 index 00000000..cec36d4b --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/szr/SZRClient.java @@ -0,0 +1,372 @@ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.szr; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.URL; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.UnrecoverableKeyException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import javax.xml.namespace.QName; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import javax.xml.ws.BindingProvider; +import javax.xml.ws.Dispatch; +import javax.xml.ws.WebServiceContext; +import javax.xml.ws.handler.Handler; + +import org.apache.commons.lang3.StringUtils; +import org.apache.cxf.configuration.jsse.TLSClientParameters; +import org.apache.cxf.endpoint.Client; +import org.apache.cxf.frontend.ClientProxy; +import org.apache.cxf.jaxws.DispatchImpl; +import org.apache.cxf.transport.http.HTTPConduit; +import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; +import org.apache.xpath.XPathAPI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.w3._2000._09.xmldsig.KeyValueType; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.Constants; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception.SZRCommunicationException; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.utils.LoggingHandler; +import at.gv.egiz.eaaf.core.api.data.XMLNamespaceConstants; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.impl.utils.DOMUtils; +import at.gv.egiz.eaaf.core.impl.utils.FileUtils; +import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils; +import szrservices.GetBPK; +import szrservices.GetBPKResponse; +import szrservices.GetIdentityLink; +import szrservices.GetIdentityLinkResponse; +import szrservices.IdentityLinkType; +import szrservices.PersonInfoType; +import szrservices.SZR; +import szrservices.SZRException_Exception; + +@Service("SZRClientForeIDAS") +public class SZRClient { + private static final Logger log = LoggerFactory.getLogger(SZRClient.class); + + private static final String CLIENT_DEFAULT = "DefaultClient"; + private static final String CLIENT_RAW = "RawClient"; + + @Autowired private IConfiguration basicConfig; + @Resource private WebServiceContext wsContext; + + //client for anything, without identitylink + private SZR szr = null; + + //RAW client is needed for identitylink + private Dispatch dispatch = null; + + + private SZRService szrService = null; + private String szrURL = null; + private QName qname = null; + + public IdentityLinkType getIdentityLink(PersonInfoType personInfo, List keyValue, Boolean insertERnP) throws SZRCommunicationException { + try { + return szr.getIdentityLink( + personInfo, + keyValue, + insertERnP); + + } catch (SZRException_Exception e) { + log.warn("SZR communication FAILED. Reason: " + e.getMessage(), e); + throw new SZRCommunicationException("ernb.02", new Object[] {e.getMessage()}, e); + + } + + } + + public IdentityLinkType getIdentityLinkInRawMode(PersonInfoType personInfo, List keyValue, Boolean insertERnP) throws SZRCommunicationException { + try { + GetIdentityLink getIDL = new GetIdentityLink(); + getIDL.setInsertERnP(insertERnP); + getIDL.setPersonInfo(personInfo); + getIDL.getKeyValue().addAll(keyValue); + + JAXBContext jaxbContext = JAXBContext.newInstance(GetIdentityLink.class); + Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); + + final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + jaxbMarshaller.marshal(getIDL, outputStream); + outputStream.flush(); + + Source source = new StreamSource(new ByteArrayInputStream(outputStream.toByteArray())); + outputStream.close(); + + log.trace("Requesting SZR ... "); + Source response = dispatch.invoke(source); + log.trace("Receive RAW response from SZR"); + + byte[] szrResponse = sourceToByteArray(response); + JAXBContext ctx = JAXBContext.newInstance(IdentityLinkType.class + .getPackage().getName()); + GetIdentityLinkResponse jaxbElement = (GetIdentityLinkResponse) ctx + .createUnmarshaller().unmarshal(new ByteArrayInputStream(szrResponse)); + + + //build response + log.trace(new String(szrResponse)); + log.trace("Signature successfully created. Extracting from MOA-SS container."); + + // ok, we have success + Document doc = DOMUtils.parseDocument( + new ByteArrayInputStream(szrResponse), + true, XMLNamespaceConstants.ALL_SCHEMA_LOCATIONS, null, null + ); + String xpathExpression = "//saml:Assertion"; + Element nsNode = doc.createElementNS("urn:oasis:names:tc:SAML:1.0:assertion", "saml:NSNode"); + + log.trace("Selecting signed doc " + xpathExpression); + Element documentNode = (Element) XPathAPI.selectSingleNode(doc, + xpathExpression, nsNode); + log.trace("Signed document: " + DOMUtils.serializeNode(documentNode)); + + + IdentityLinkType idl = new IdentityLinkType(); + idl.setAssertion(documentNode); + idl.setPersonInfo(jaxbElement.getGetIdentityLinkReturn().getPersonInfo()); + + return idl; + + + //IdentityLinkType idlResp = this.szr.getIdentityLink(personInfo, keyValue, insertERnP); + + } catch ( Exception e) { + log.warn("SZR communication FAILED. Reason: " + e.getMessage(), e); + throw new SZRCommunicationException("ernb.02", new Object[] {e.getMessage()}, e); + + } + + } + + public String getBPK(PersonInfoType personInfo, String target, String vkz) throws SZRCommunicationException { + try { + GetBPK parameters = new GetBPK(); + parameters.setPersonInfo(personInfo); + parameters.setBereichsKennung(target); + parameters.setVKZ(vkz); + GetBPKResponse result = this.szr.getBPK(parameters); + + return result.getGetBPKReturn(); + + } catch (SZRException_Exception e) { + log.warn("SZR communication FAILED. Reason: " + e.getMessage(), e); + throw new SZRCommunicationException("ernb.02", new Object[] {e.getMessage()}, e); + + } + + } + + + @PostConstruct + private void initialize() { + log.info("Starting SZR-Client initialization .... "); + URL url = SZRClient.class.getResource("/szr_client/SZR-1.WSDL"); + + boolean useTestSZR = basicConfig.getBasicMOAIDConfigurationBoolean( + Constants.CONIG_PROPS_EIDAS_SZRCLIENT_USETESTSERVICE, + true); + + if (useTestSZR) { + log.debug("Initializing SZR test environment configuration."); + qname = SZRService.SZRTestumgebung; + szrService = new SZRService(url, new QName("urn:SZRServices", "SZRService")); + szr = szrService.getSZRTestumgebung(); + szrURL = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_ENDPOINT_TEST); + + + } else { + log.debug("Initializing SZR productive configuration."); + qname = SZRService.SZRProduktionsumgebung; + szrService = new SZRService(url, new QName("urn:SZRServices", "SZRService")); + szr = szrService.getSZRProduktionsumgebung(); + szrURL = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_ENDPOINT_PROD); + + } + + //create raw client; + dispatch = szrService.createDispatch(qname, Source.class, javax.xml.ws.Service.Mode.PAYLOAD); + + if (StringUtils.isEmpty(szrURL)) { + log.error("No SZR service-URL found. SZR-Client initalisiation failed."); + throw new RuntimeException("No SZR service URL found. SZR-Client initalisiation failed."); + + } + + log.info("Use SZR service-URL: " + szrURL); + injectBindingProvider((BindingProvider) szr, CLIENT_DEFAULT); + injectBindingProvider((BindingProvider) dispatch, CLIENT_RAW); + + log.debug("Inject HTTP client settings ... "); + injectHTTPClient(szr, CLIENT_DEFAULT); + injectHTTPClient(dispatch, CLIENT_RAW); + + log.info("SZR-Client initialization successfull"); + } + + private void injectHTTPClient(Object raw, String clientType) { + //extract client from implementation + Client client = null; + if (raw instanceof DispatchImpl) + client = ((DispatchImpl)raw).getClient(); + else if (raw instanceof Client) + client = ClientProxy.getClient(raw); + else + throw new RuntimeException("SOAP Client for SZR connection is of UNSUPPORTED type: " + raw.getClass().getName()); + + //set basic connection policies + HTTPConduit http = (HTTPConduit) client.getConduit(); + + //set timeout policy + HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); + httpClientPolicy.setConnectionTimeout( + Integer.parseInt(basicConfig.getBasicConfiguration( + Constants.CONIG_PROPS_EIDAS_SZRCLIENT_TIMEOUT_CONNECTION, + Constants.HTTP_CLIENT_DEFAULT_TIMEOUT_CONNECTION)) * 1000); + httpClientPolicy.setReceiveTimeout( + Integer.parseInt(basicConfig.getBasicConfiguration( + Constants.CONIG_PROPS_EIDAS_SZRCLIENT_TIMEOUT_RESPONSE, + Constants.HTTP_CLIENT_DEFAULT_TIMEOUT_RESPONSE)) * 1000); + http.setClient(httpClientPolicy); + + //inject SSL context in case of https + if (szrURL.toLowerCase().startsWith("https")) { + log.debug("Adding SSLContext to client: " + clientType +" ... "); + TLSClientParameters tlsParams = new TLSClientParameters(); + tlsParams.setSSLSocketFactory(createSSLContext(clientType).getSocketFactory()); + http.setTlsClientParameters(tlsParams ); + log.info("SSLContext initialized for client: " + clientType); + + } + + } + + private void injectBindingProvider(BindingProvider bindingProvider, String clientType) { + Map requestContext = bindingProvider.getRequestContext(); + requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, szrURL); + + log.trace("Adding JAX-WS request/response trace handler to client: " + clientType); + List handlerList = bindingProvider.getBinding().getHandlerChain(); + if (handlerList == null) { + handlerList = new ArrayList(); + bindingProvider.getBinding().setHandlerChain(handlerList); + + } + + //add logging handler to trace messages if required + if (basicConfig.getBasicMOAIDConfigurationBoolean( + Constants.CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_TRACEMESSAGES, + false)) { + LoggingHandler loggingHandler = new LoggingHandler(); + handlerList.add(loggingHandler); + + } + } + + private SSLContext createSSLContext(String clientType) { + try { + SSLContext context = SSLContext.getInstance("TLS"); + + //initialize key-mangager for SSL client-authentication + KeyManager[] keyManager = null; + String keyStorePath = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_SSL_KEYSTORE_PATH); + String keyStorePassword = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_SSL_KEYSTORE_PASSWORD); + if (StringUtils.isNotEmpty(keyStorePath)) { + log.trace("Find keyStore path: " + keyStorePath + " Injecting SSL client certificate ... "); + try { + KeyStore keyStore = KeyStoreUtils.loadKeyStore( + FileUtils.makeAbsoluteURL(keyStorePath, basicConfig.getConfigurationRootDirectory()), + keyStorePassword); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(keyStore, keyStorePassword.toCharArray()); + keyManager = kmf.getKeyManagers(); + log.debug("SSL client certificate injected to client: " + clientType); + + } catch (KeyStoreException | IOException | UnrecoverableKeyException e) { + log.error("Can NOT load SSL client certificate from path: " + keyStorePath); + throw new RuntimeException("Can NOT load SSL client certificate from path: " + keyStorePath, e); + + } + } + + + //initialize SSL TrustStore + TrustManager[] trustManager = null; + String trustStorePath = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_SSL_TRUSTSTORE_PATH); + String trustStorePassword = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_SSL_TRUSTSTORE_PASSWORD); + if (StringUtils.isNotEmpty(trustStorePath)) { + log.trace("Find trustStore path: " + trustStorePath + " Injecting SSL TrustStore ... "); + try { + KeyStore trustStore = KeyStoreUtils.loadKeyStore( + FileUtils.makeAbsoluteURL(trustStorePath, basicConfig.getConfigurationRootDirectory()), + trustStorePassword); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(trustStore); + trustManager = tmf.getTrustManagers(); + log.debug("SSL TrustStore injected to client: " + clientType); + + } catch (KeyStoreException | IOException e) { + log.error("Can NOT open SSL TrustStore from path: " + trustStorePath); + throw new RuntimeException("Can NOT open SSL TrustStore from path: " + trustStorePath, e); + + } + + } + + + context.init(keyManager, trustManager, new SecureRandom()); + return context; + + } catch (NoSuchAlgorithmException | KeyManagementException e) { + log.error("SSLContext initialization FAILED.", e); + throw new RuntimeException("SSLContext initialization FAILED.", e); + + } + + } + + private byte[] sourceToByteArray(Source result) throws TransformerException { + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer(); + transformer.setOutputProperty("omit-xml-declaration", "yes"); + transformer.setOutputProperty("method", "xml"); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + StreamResult streamResult = new StreamResult(); + streamResult.setOutputStream(out); + transformer.transform(result, streamResult); + return out.toByteArray(); + } + + + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/szr/SZRService.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/szr/SZRService.java new file mode 100644 index 00000000..ce2a1324 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/szr/SZRService.java @@ -0,0 +1,139 @@ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.szr; + +import java.net.URL; + +import javax.xml.namespace.QName; +import javax.xml.ws.Service; +import javax.xml.ws.WebEndpoint; +import javax.xml.ws.WebServiceClient; +import javax.xml.ws.WebServiceFeature; + +import szrservices.SZR; + +/** + * This class was generated by Apache CXF 3.1.16 + * 2018-07-10T09:36:01.466+02:00 + * Generated source version: 3.1.16 + * + */ +@WebServiceClient(name = "SZRService", + wsdlLocation = "./src/main/resources/szr_client/SZR-1.WSDL", + targetNamespace = "urn:SZRServices") +public class SZRService extends Service { + + public final static URL WSDL_LOCATION; + + public final static QName SERVICE = new QName("urn:SZRServices", "SZRService"); + public final static QName SZRProduktionsumgebung = new QName("urn:SZRServices", "SZRProduktionsumgebung"); + public final static QName SZRTestumgebung = new QName("urn:SZRServices", "SZRTestumgebung"); + public final static QName SZRBusinesspartnerTestumgebung = new QName("urn:SZRServices", "SZRBusinesspartnerTestumgebung"); + static { + URL url = SZRService.class.getResource("./src/main/resources/szr_client/SZR-1.WSDL"); + if (url == null) { + url = SZRService.class.getClassLoader().getResource("/szr_client/SZR-1.WSDL"); + } + if (url == null) { + java.util.logging.Logger.getLogger(SZRService.class.getName()) + .log(java.util.logging.Level.INFO, + "Can not initialize the default wsdl from {0}", "/szr_client/SZR-1.WSDL"); + } + WSDL_LOCATION = url; + + } + + public SZRService(URL wsdlLocation) { + super(wsdlLocation, SERVICE); + } + + public SZRService(URL wsdlLocation, QName serviceName) { + super(wsdlLocation, serviceName); + } + + public SZRService() { + super(WSDL_LOCATION, SERVICE); + } + + public SZRService(WebServiceFeature ... features) { + super(WSDL_LOCATION, SERVICE, features); + } + + public SZRService(URL wsdlLocation, WebServiceFeature ... features) { + super(wsdlLocation, SERVICE, features); + } + + public SZRService(URL wsdlLocation, QName serviceName, WebServiceFeature ... features) { + super(wsdlLocation, serviceName, features); + } + + + + + /** + * + * @return + * returns SZR + */ + @WebEndpoint(name = "SZRProduktionsumgebung") + public SZR getSZRProduktionsumgebung() { + return super.getPort(SZRProduktionsumgebung, SZR.class); + } + + /** + * + * @param features + * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. + * @return + * returns SZR + */ + @WebEndpoint(name = "SZRProduktionsumgebung") + public SZR getSZRProduktionsumgebung(WebServiceFeature... features) { + return super.getPort(SZRProduktionsumgebung, SZR.class, features); + } + + + /** + * + * @return + * returns SZR + */ + @WebEndpoint(name = "SZRTestumgebung") + public SZR getSZRTestumgebung() { + return super.getPort(SZRTestumgebung, SZR.class); + } + + /** + * + * @param features + * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. + * @return + * returns SZR + */ + @WebEndpoint(name = "SZRTestumgebung") + public SZR getSZRTestumgebung(WebServiceFeature... features) { + return super.getPort(SZRTestumgebung, SZR.class, features); + } + + + /** + * + * @return + * returns SZR + */ + @WebEndpoint(name = "SZRBusinesspartnerTestumgebung") + public SZR getSZRBusinesspartnerTestumgebung() { + return super.getPort(SZRBusinesspartnerTestumgebung, SZR.class); + } + + /** + * + * @param features + * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. + * @return + * returns SZR + */ + @WebEndpoint(name = "SZRBusinesspartnerTestumgebung") + public SZR getSZRBusinesspartnerTestumgebung(WebServiceFeature... features) { + return super.getPort(SZRBusinesspartnerTestumgebung, SZR.class, features); + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java new file mode 100644 index 00000000..c5d33b73 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java @@ -0,0 +1,380 @@ +/******************************************************************************* + *******************************************************************************/ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.tasks; + +import java.io.InputStream; +import java.math.BigInteger; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.Base64Utils; +import org.w3._2000._09.xmldsig.KeyValueType; +import org.w3._2000._09.xmldsig.RSAKeyValueType; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +import at.asitplus.eidas.specific.connector.MSConnectorEventCodes; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.Constants; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception.SZRCommunicationException; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASAttributeException; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.szr.SZRClient; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.utils.eIDASResponseUtils; +import at.gv.e_government.reference.namespace.persondata._20020228.PersonNameType; +import at.gv.e_government.reference.namespace.persondata._20020228.PhysicalPersonType; +import at.gv.egiz.eaaf.core.api.data.EAAFConstants; +import at.gv.egiz.eaaf.core.api.data.PVPAttributeDefinitions; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; +import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; +import at.gv.egiz.eaaf.core.exceptions.EAAFException; +import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; +import at.gv.egiz.eaaf.core.impl.data.Pair; +import at.gv.egiz.eaaf.core.impl.data.Trible; +import at.gv.egiz.eaaf.core.impl.idp.auth.builder.BPKBuilder; +import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper; +import at.gv.egiz.eaaf.core.impl.idp.auth.data.SimpleIdentityLinkAssertionParser; +import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; +import at.gv.egiz.eaaf.core.impl.utils.DOMUtils; +import at.gv.egiz.eaaf.core.impl.utils.XPathUtils; +import eu.eidas.auth.commons.attribute.AttributeDefinition; +import eu.eidas.auth.commons.attribute.AttributeValue; +import eu.eidas.auth.commons.light.ILightResponse; +import eu.eidas.auth.commons.protocol.eidas.impl.PostalAddress; +import szrservices.IdentityLinkType; +import szrservices.PersonInfoType; +import szrservices.TravelDocumentType; + +/** + * @author tlenz + * + */ +@Component("CreateIdentityLinkTask") +public class CreateIdentityLinkTask extends AbstractAuthServletTask { + private static final Logger log = LoggerFactory.getLogger(CreateIdentityLinkTask.class); + + //@Autowired private eIDASAttributeRegistry attrRegistry; + @Autowired private IConfiguration basicConfig; + @Autowired private SZRClient szrClient; + + + /* (non-Javadoc) + * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + @Override + public void execute(ExecutionContext executionContext, + HttpServletRequest request, HttpServletResponse response) + throws TaskExecutionException { + try{ + AuthProcessDataWrapper authProcessData = pendingReq.getSessionData(AuthProcessDataWrapper.class); + ILightResponse eIDASResponse = authProcessData.getGenericDataFromSession( + Constants.DATA_FULL_EIDAS_RESPONSE, ILightResponse.class); + Map simpleAttrMap = converteIDASAttrToSimpleMap(eIDASResponse.getAttributes().getAttributeMap()); + + IIdentityLink identityLink = null; + String bPK = null; + + //extract attributes + Object eIdentifierObj = simpleAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER); + Object familyNameObj = simpleAttrMap.get(Constants.eIDAS_ATTR_CURRENTFAMILYNAME); + Object givenNameObj = simpleAttrMap.get(Constants.eIDAS_ATTR_CURRENTGIVENNAME); + Object dateOfBirthObj = simpleAttrMap.get(Constants.eIDAS_ATTR_DATEOFBIRTH); + + //check if availabe + if (eIdentifierObj == null || !(eIdentifierObj instanceof String)) + throw new eIDASAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER); + + if (familyNameObj == null || !(familyNameObj instanceof String)) + throw new eIDASAttributeException(Constants.eIDAS_ATTR_CURRENTFAMILYNAME); + + if (givenNameObj == null || !(givenNameObj instanceof String)) + throw new eIDASAttributeException(Constants.eIDAS_ATTR_CURRENTGIVENNAME); + + if (dateOfBirthObj == null || !(dateOfBirthObj instanceof DateTime)) + throw new eIDASAttributeException(Constants.eIDAS_ATTR_DATEOFBIRTH); + + //connect SZR-Gateway + if(basicConfig.getBasicMOAIDConfigurationBoolean( + Constants.CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_USEDUMMY, false)) { + log.warn("SZR-Dummy IS ACTIVE! IdentityLink is NOT VALID!!!!"); + // create fake IdL + // - fetch IdL template from resources + InputStream s = CreateIdentityLinkTask.class.getResourceAsStream("/resources/xmldata/fakeIdL_IdL_template.xml"); + Element idlTemplate = DOMUtils.parseXmlValidating(s); + + identityLink = new SimpleIdentityLinkAssertionParser(idlTemplate).parseIdentityLink(); + + // replace data + Element idlassertion = identityLink.getSamlAssertion(); + + // - set fake baseID; + Node prIdentification = XPathUtils.selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH); + prIdentification.getFirstChild().setNodeValue((String) eIdentifierObj); + + //build personal identifier which looks like a baseID +// String fakeBaseID = new BPKBuilder().buildBPK(eIdentifier, "baseID"); +// Logger.info("Map eIDAS eIdentifier:" + eIdentifier + " to fake baseID:" + fakeBaseID); +// prIdentification.getFirstChild().setNodeValue(fakeBaseID); + + // - set last name + Node prFamilyName = XPathUtils.selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_FAMILY_NAME_XPATH); + prFamilyName.getFirstChild().setNodeValue((String) familyNameObj); + + // - set first name + Node prGivenName = XPathUtils.selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_GIVEN_NAME_XPATH); + prGivenName.getFirstChild().setNodeValue((String) givenNameObj); + + // - set date of birth + Node prDateOfBirth = XPathUtils.selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_DATE_OF_BIRTH_XPATH); + String formatedDateOfBirth = new SimpleDateFormat("yyyy-MM-dd").format(((DateTime)dateOfBirthObj).toDate()); + prDateOfBirth.getFirstChild().setNodeValue(formatedDateOfBirth); + + identityLink = new SimpleIdentityLinkAssertionParser(idlassertion).parseIdentityLink(); + + Pair bPKCalc = new BPKBuilder().generateAreaSpecificPersonIdentifier( + identityLink.getIdentificationValue(), + identityLink.getIdentificationType(), + pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier()); + bPK = bPKCalc.getFirst(); + + + } else { + //contact SZR Gateway + log.debug("Starting connecting SZR Gateway"); + PersonInfoType personInfo = new PersonInfoType(); + PersonNameType personName = new PersonNameType(); + PhysicalPersonType naturalPerson = new PhysicalPersonType(); + TravelDocumentType eDocument = new TravelDocumentType(); + + naturalPerson.setName(personName ); + personInfo.setPerson(naturalPerson ); + personInfo.setTravelDocument(eDocument ); + + //parse some eID attributes + String dateOfBirth = new SimpleDateFormat("yyyy-MM-dd").format(((DateTime)dateOfBirthObj).toDate()); + Trible eIdentifier = + eIDASResponseUtils.parseEidasPersonalIdentifier((String)eIdentifierObj); + String uniqueId = (String)eIdentifierObj; + String citizenCountry = eIdentifier.getFirst(); + + //person information + personName.setFamilyName((String)familyNameObj); + personName.setGivenName((String)givenNameObj); + naturalPerson.setDateOfBirth(dateOfBirth); + eDocument.setIssuingCountry(citizenCountry); + eDocument.setDocumentNumber(uniqueId); + + //eID document information + eDocument.setDocumentType(basicConfig.getBasicConfiguration( + Constants.CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_EDOCUMENTTYPE, + Constants.SZR_CONSTANTS_DEFAULT_DOCUMENT_TYPE)); + + //TODO: that should be removed + eDocument.setIssueDate(basicConfig.getBasicConfiguration( + Constants.CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_ISSUING_DATE, + Constants.SZR_CONSTANTS_DEFAULT_ISSUING_DATE)); + eDocument.setIssuingAuthority(basicConfig.getBasicConfiguration( + Constants.CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_ISSUING_AUTHORITY, + Constants.SZR_CONSTANTS_DEFAULT_ISSUING_AUTHORITY)); + + //TODO: keys are not available in eIDAS + List keyValue = dummyCodeForKeys(); + + /*TODO: + * Validate if IDL signature is valid after using this method + * MAYBE we had to switch to 'getIdentityLinkInRawMode' method! + */ + IdentityLinkType result = szrClient.getIdentityLink( + personInfo, + keyValue, + basicConfig.getBasicMOAIDConfigurationBoolean( + Constants.CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_INSERTERNB, + true) + ); + + Element idlFromSZR = (Element)result.getAssertion(); + identityLink = new SimpleIdentityLinkAssertionParser(idlFromSZR).parseIdentityLink(); + + + //get bPK from SZR + bPK = szrClient.getBPK( + personInfo, + pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier(), + basicConfig.getBasicConfiguration( + Constants.CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_VKZ, + "no VKZ defined")); + + } + + if (identityLink == null) { + log.error("ERnB did not return an identity link."); + throw new SZRCommunicationException("ernb.00", null); + + } + revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.SZR_IDL_RECEIVED); + + + if (bPK == null) { + log.error("ERnB did not return a bPK for target: " + pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier()); + throw new SZRCommunicationException("ernb.01", null); + + } + revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.SZR_BPK_RECEIVED); + + log.debug("ERnB communication was successfull"); + + authProcessData.setForeigner(true); + authProcessData.setIdentityLink(identityLink); + authProcessData.setGenericDataToSession( + PVPAttributeDefinitions.EID_ISSUING_NATION_NAME, + eIDASResponseUtils.parseEidasPersonalIdentifier((String) simpleAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER)).getFirst()); + + //set bPK and bPKType into auth session + authProcessData.setGenericDataToSession( + PVPAttributeDefinitions.BPK_NAME, + extendBPKbyPrefix( + bPK, + pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier()) + ); + authProcessData.setGenericDataToSession( + PVPAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME, + pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier()); + + + + //store pending-request + requestStoreage.storePendingRequest(pendingReq); + + } catch (eIDASAttributeException e) { + throw new TaskExecutionException(pendingReq, "Minimum required eIDAS attributeset not found.", e); + + } catch (EAAFException e) { + throw new TaskExecutionException(pendingReq, "IdentityLink generation for foreign person FAILED.", e); + + } catch (Exception e) { + log.error("IdentityLink generation for foreign person FAILED.", e); + throw new TaskExecutionException(pendingReq, "IdentityLink generation for foreign person FAILED.", e); + + } + } + + private List dummyCodeForKeys() { + if (basicConfig.getBasicMOAIDConfigurationBoolean( + Constants.CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_KEYS_USEDUMMY, + false)) { + List keyvalueList = new ArrayList(); + try { + PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Constants.SZR_CONSTANTS_DEFAULT_PUBL_KEY); + KeyFactory kf = KeyFactory.getInstance("RSA"); + + PublicKey pb = kf.generatePublic(spec); + + RSAPublicKey rsapb = (RSAPublicKey)pb; + BigInteger modulus = rsapb.getModulus(); + BigInteger exponent = rsapb.getPublicExponent(); + + // set key values + RSAKeyValueType rsa = new RSAKeyValueType(); + rsa.setExponent(new String(Base64Utils.encode(exponent.toByteArray()))); + rsa.setModulus(new String(Base64Utils.encode(modulus.toByteArray()))); + + KeyValueType key = new KeyValueType(); + key.setRSAKeyValue(rsa); + + keyvalueList.add(key); + + return keyvalueList; + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + log.error("TestCode has an internal ERROR", e); + + } + + } + + return null; + + } + + private String extendBPKbyPrefix(String bpk, String type) { + String bPKType = null; + + if (type.startsWith(EAAFConstants.URN_PREFIX_WBPK)) + bPKType = type.substring((EAAFConstants.URN_PREFIX_WBPK).length()); + + else if (type.startsWith(EAAFConstants.URN_PREFIX_CDID)) + bPKType = type.substring((EAAFConstants.URN_PREFIX_CDID).length()); + + else if (type.startsWith(EAAFConstants.URN_PREFIX_EIDAS)) + bPKType = type.substring((EAAFConstants.URN_PREFIX_EIDAS).length()); + + + if (bPKType != null ) { + log.trace("Authenticate user with bPK/wbPK " + bpk + " and Type=" + bPKType); + return bPKType + ":" + bpk; + + } else { + log.warn("Service Provider Target with: " + type + " is NOT supported. Set bPK as it is ..."); + return bpk; + + } + + } + + //TODO: update for complexe attributes + private Map converteIDASAttrToSimpleMap( + ImmutableMap, ImmutableSet>> attributeMap) { + Map result = new HashMap(); + + for (AttributeDefinition el : attributeMap.keySet()) { + + final Class parameterizedType = el.getParameterizedType(); + if ((DateTime.class).equals(parameterizedType)) { + DateTime attribute = eIDASResponseUtils.translateDateAttribute(el, attributeMap.get(el).asList()); + if (attribute != null) + result.put(el.getFriendlyName(), attribute); + else + log.info("Ignore empty 'DateTime' attribute"); + + } else if ((PostalAddress.class).equals(parameterizedType)) { + PostalAddress addressAttribute = eIDASResponseUtils.translateAddressAttribute(el, attributeMap.get(el).asList()); + if (addressAttribute != null) + result.put(el.getFriendlyName(), addressAttribute); + else + log.info("Ignore empty 'PostalAddress' attribute"); + + } else { + List natPersonIdObj = eIDASResponseUtils.translateStringListAttribute(el, attributeMap.get(el).asList()); + String stringAttr = natPersonIdObj.get(0); + if (StringUtils.isNotEmpty(stringAttr)) + result.put(el.getFriendlyName(), stringAttr); + else + log.info("Ignore empty 'String' attribute"); + + } + } + + return result; + } + + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java new file mode 100644 index 00000000..74c98de1 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java @@ -0,0 +1,306 @@ +/******************************************************************************* + *******************************************************************************/ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.tasks; + +import java.util.Map; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; +import org.springframework.web.util.UriComponentsBuilder; + +import com.google.common.collect.ImmutableSortedSet; + +import at.asitplus.eidas.specific.connector.MSConnectorEventCodes; +import at.asitplus.eidas.specific.connector.MSeIDASNodeConstants; +import at.asitplus.eidas.specific.connector.gui.StaticGuiBuilderConfiguration; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.Constants; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASAuthenticationException; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.service.eIDASAttributeRegistry; +import at.gv.egiz.eaaf.core.api.data.EAAFConstants; +import at.gv.egiz.eaaf.core.api.gui.IGUIFormBuilder; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration; +import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; +import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage; +import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; +import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; +import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; +import eu.eidas.auth.commons.EidasParameterKeys; +import eu.eidas.auth.commons.attribute.AttributeDefinition; +import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; +import eu.eidas.auth.commons.light.ILightRequest; +import eu.eidas.auth.commons.light.impl.LightRequest; +import eu.eidas.auth.commons.protocol.eidas.SpType; +import eu.eidas.auth.commons.tx.BinaryLightToken; +import eu.eidas.specificcommunication.BinaryLightTokenHelper; +import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames; +import eu.eidas.specificcommunication.exception.SpecificCommunicationException; +import eu.eidas.specificcommunication.protocol.impl.SpecificConnectorCommunicationServiceImpl; + +/** + * @author tlenz + * + */ +@Component("ConnecteIDASNodeTask") +public class GenerateAuthnRequestTask extends AbstractAuthServletTask { + private static final Logger log = LoggerFactory.getLogger(GenerateAuthnRequestTask.class); + + @Autowired IConfiguration basicConfig; + @Autowired eIDASAttributeRegistry attrRegistry; + @Autowired ApplicationContext context; + @Autowired ITransactionStorage transactionStore; + @Autowired IGUIFormBuilder guiBuilder; + + @Override + public void execute(ExecutionContext executionContext, + HttpServletRequest request, HttpServletResponse response) + throws TaskExecutionException { + + try{ + //get service-provider configuration + ISPConfiguration spConfig = pendingReq.getServiceProviderConfiguration(); + + // get target, environment and validate citizen countryCode + String citizenCountryCode = (String) executionContext.get(MSeIDASNodeConstants.REQ_PARAM_SELECTED_COUNTRY); + String environment = (String) executionContext.get(MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT); + + if (StringUtils.isEmpty(citizenCountryCode)) { + // illegal state; task should not have been executed without a selected country + throw new eIDASAuthenticationException("eidas.03", new Object[] { "" }); + + } + + //TODO: maybe add countryCode validation before request ref. impl. eIDAS node + log.debug("Request eIDAS auth. for citizen of country: " + citizenCountryCode); + revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.COUNTRY_SELECTED, citizenCountryCode); + + //build eIDAS AuthnRequest + LightRequest.Builder authnRequestBuilder = LightRequest.builder(); + authnRequestBuilder.id(UUID.randomUUID().toString()); + + + String issur = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_ENTITYID); + if (StringUtils.isEmpty(issur)) { + log.error("Found NO 'eIDAS node issuer' in configuration. Authentication NOT possible!"); + throw new EAAFConfigurationException("config.27", + new Object[] {"Application config containts NO " + Constants.CONIG_PROPS_EIDAS_NODE_ENTITYID }); + + } + authnRequestBuilder.issuer(issur); + + + //TODO: set matching mode if eIDAS ref. impl. support this method + + + //TODO: update if eIDAS ref. impl. supports exact matching for non-notified LoA schemes + String loa = EAAFConstants.EIDAS_LOA_HIGH; + if (spConfig.getRequiredLoA() != null) { + if (spConfig.getRequiredLoA().isEmpty()) + log.info("No eIDAS LoA requested. Use LoA HIGH as default"); + + else { + if (spConfig.getRequiredLoA().size() > 1 ) + log.info("Currently only ONE requested LoA is supported for service provider. Use first one ... "); + + loa = spConfig.getRequiredLoA().get(0); + + } + } + + log.debug("Request eIdAS node with LoA: " + loa); + authnRequestBuilder.levelOfAssurance(loa); + + //set correct SPType for requested target sector + String publicSectorTargetSelector = basicConfig.getBasicConfiguration( + Constants.CONIG_PROPS_EIDAS_NODE_PUBLICSECTOR_TARGETS, + Constants.POLICY_DEFAULT_ALLOWED_TARGETS); + Pattern p = Pattern.compile(publicSectorTargetSelector); + Matcher m = p.matcher(spConfig.getAreaSpecificTargetIdentifier()); + if (m.matches()) { + log.debug("Map " + spConfig.getAreaSpecificTargetIdentifier() + " to 'PublicSector'"); + authnRequestBuilder.spType(SpType.PUBLIC.getValue()); + + //TODO: only for eIDAS ref. node 2.0 and 2.1 because it need 'Providername' for any SPType + String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class); + if (StringUtils.isNotEmpty(providerName) + && basicConfig.getBasicMOAIDConfigurationBoolean( + Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME, + false) + ) + authnRequestBuilder.providerName(providerName); + + } else { + log.debug("Map " + spConfig.getAreaSpecificTargetIdentifier() + " to 'PrivateSector'"); + authnRequestBuilder.spType(SpType.PRIVATE.getValue()); + + //TODO: switch to RequesterId in further version + //set provider name for private sector applications + String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class); + if (StringUtils.isNotEmpty(providerName)) + authnRequestBuilder.providerName(providerName); + + } + + //set nameIDFormat + authnRequestBuilder.nameIdFormat(Constants.eIDAS_REQ_NAMEID_FORMAT); + + //set citizen country code for foreign uses + authnRequestBuilder.citizenCountryCode(citizenCountryCode); + + //set relay state + authnRequestBuilder.relayState(pendingReq.getPendingRequestId()); + + //build and add requested attribute set + ImmutableAttributeMap reqAttrMap = translateToEidasAttributes(attrRegistry.getAttributeSetFromConfiguration()); + authnRequestBuilder.requestedAttributes(reqAttrMap); + + //build request + LightRequest lightAuthnReq = authnRequestBuilder.build(); + + //put request into cache + BinaryLightToken token = putRequestInCommunicationCache(lightAuthnReq); + final String tokenBase64 = BinaryLightTokenHelper.encodeBinaryLightTokenBase64(token); + + //Workaround, because eIDAS node ref. impl. does not return relayState + if (basicConfig.getBasicMOAIDConfigurationBoolean( + Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_USEREQUESTIDASTRANSACTIONIDENTIFIER, + false)) { + log.trace("Put lightRequestId into transactionstore as session-handling backup"); + transactionStore.put(lightAuthnReq.getId(), pendingReq.getPendingRequestId(), -1); + + } + + //select forward URL regarding the selected environment + String forwardURL = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL); + if (StringUtils.isNotEmpty(environment)) + forwardURL = selectedForwardURLForEnvironment(environment); + + if (StringUtils.isEmpty(forwardURL)) { + log.warn("NO ForwardURL defined in configuration. Can NOT forward to eIDAS node! Process stops"); + throw new EAAFConfigurationException("config.08", new Object[] {Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL}); + + } + log.debug("ForwardURL: " + forwardURL + " selected to forward eIDAS request"); + + if (basicConfig.getBasicConfiguration( + Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD, + Constants.FORWARD_METHOD_GET + ).equals(Constants.FORWARD_METHOD_GET)) { + + log.debug("Use http-redirect for eIDAS node forwarding ... "); + //send redirect + UriComponentsBuilder redirectUrl = UriComponentsBuilder.fromHttpUrl(forwardURL); + redirectUrl.queryParam(EidasParameterKeys.TOKEN.toString(), tokenBase64); + response.sendRedirect(redirectUrl.build().encode().toString()); + + } else { + log.debug("Use http-post for eIDAS node forwarding ... "); + StaticGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration( + basicConfig, + pendingReq, + Constants.TEMPLATE_POST_FORWARD_NAME, + null); + + config.putCustomParameter(Constants.TEMPLATE_POST_FORWARD_ENDPOINT, forwardURL); + config.putCustomParameter(Constants.TEMPLATE_POST_FORWARD_TOKEN_NAME, + EidasParameterKeys.TOKEN.toString()); + config.putCustomParameter(Constants.TEMPLATE_POST_FORWARD_TOKEN_VALUE, + tokenBase64); + + guiBuilder.build(response, config, "BKU-Selection form"); + + } + + revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.EIDAS_NODE_CONNECTED, lightAuthnReq.getId()); + + + } catch (eIDASAuthenticationException e) { + throw new TaskExecutionException(pendingReq, "eIDAS AuthnRequest generation FAILED.", e); + + } catch (Exception e) { + log.warn("eIDAS AuthnRequest generation FAILED.", e); + throw new TaskExecutionException(pendingReq, e.getMessage(), e); + + } + + } + + /** + * Select a forward URL from configuration for a specific environment + *

+ * Info: This method is needed, because eIDAS Ref. Impl only supports one countrycode on each instance. + * In consequence, more than one eIDAS Ref. Impl nodes are required to support producation, testing, or QS stages + * for one country by using one ms-specific eIDAS connector + * + * @param environment Environment selector from CountrySlection page + * @return + */ + private String selectedForwardURLForEnvironment(String environment) { + log.trace("Starting endpoint selection process for environment: " + environment + " ... "); + if (environment.equalsIgnoreCase(MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_PRODUCTION)) + return basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL); + + else if (environment.equalsIgnoreCase(MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_QS)) + return basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL + + "." + MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_QS); + + else if (environment.equalsIgnoreCase(MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_TESTING)) + return basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL + + "." + MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_TESTING); + + else if (environment.equalsIgnoreCase(MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_DEVELOPMENT)) + return basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL + + "." + MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_DEVELOPMENT); + + log.info("Environment selector: " + environment + " is not supported"); + return null; + + } + + private ImmutableAttributeMap translateToEidasAttributes(final Map requiredAttributes) { + ImmutableAttributeMap.Builder builder = ImmutableAttributeMap.builder(); + for (Map.Entry attribute : requiredAttributes.entrySet()) { + final String name = attribute.getKey(); + final ImmutableSortedSet> byFriendlyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(name); + if (!byFriendlyName.isEmpty()) { + final AttributeDefinition attributeDefinition = byFriendlyName.first(); + builder.put(AttributeDefinition.builder(attributeDefinition).required(attribute.getValue()).build()); + + } else + log.warn("Can NOT request UNKNOWN attribute: " + attribute.getKey() + " Ignore it!"); + + } + + return builder.build(); + + } + + private BinaryLightToken putRequestInCommunicationCache(ILightRequest iLightRequest) throws ServletException { + final BinaryLightToken binaryLightToken; + try { + final SpecificConnectorCommunicationServiceImpl springManagedSpecificConnectorCommunicationService = + (SpecificConnectorCommunicationServiceImpl) context.getBean(SpecificCommunicationDefinitionBeanNames.SPECIFIC_CONNECTOR_COMMUNICATION_SERVICE.toString()); + + binaryLightToken = springManagedSpecificConnectorCommunicationService.putRequest(iLightRequest); + + } catch (SpecificCommunicationException e) { + log.error("Unable to process specific request"); + throw new ServletException(e); + + } + + return binaryLightToken; + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/ReceiveAuthnResponseTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/ReceiveAuthnResponseTask.java new file mode 100644 index 00000000..2970c073 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/tasks/ReceiveAuthnResponseTask.java @@ -0,0 +1,97 @@ +/******************************************************************************* + *******************************************************************************/ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.tasks; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; + +import at.asitplus.eidas.specific.connector.MSConnectorEventCodes; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.Constants; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASAuthenticationException; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.service.eIDASAttributeRegistry; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.validator.eIDASResponseValidator; +import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; +import at.gv.egiz.eaaf.core.exceptions.EAAFException; +import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; +import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper; +import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; +import eu.eidas.auth.commons.light.ILightResponse; + +@Component("ReceiveResponseFromeIDASNodeTask") +public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { + private static final Logger log = LoggerFactory.getLogger(ReceiveAuthnResponseTask.class); + + @Autowired private ApplicationContext context; + @Autowired private IConfiguration basicConfig; + @Autowired private eIDASAttributeRegistry attrRegistry; + + @Override + public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) throws TaskExecutionException { + try{ + ILightResponse eIDASResponse = (ILightResponse) request.getAttribute(Constants.DATA_FULL_EIDAS_RESPONSE); + if (eIDASResponse == null) { + log.warn("NO eIDAS response-message found."); + throw new eIDASAuthenticationException("eidas.01", null); + + } + + log.debug("Receive eIDAS response with RespId:" + eIDASResponse.getId() + " for ReqId:" + eIDASResponse.getInResponseToId()); + revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.RESPONSE_FROM_EIDAS_NODE, eIDASResponse.getId()); + + + //check response StatusCode + if (!eIDASResponse.getStatus().getStatusCode().equals(Constants.SUCCESS_URI)) { + log.info("Receice eIDAS Response with StatusCode:" + eIDASResponse.getStatus().getStatusCode() + + " Subcode:" + eIDASResponse.getStatus().getSubStatusCode() + " Msg:" + eIDASResponse.getStatus().getStatusMessage()); + throw new eIDASAuthenticationException("eidas.02", new Object[]{eIDASResponse.getStatus().getStatusCode(), eIDASResponse.getStatus().getStatusMessage()}); + + } + + // extract all Attributes from response + + + + // ********************************************************** + // ******* MS-specificresponse validation ********** + // ********************************************************** + String spCountry = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, "AT"); + eIDASResponseValidator.validateResponse(pendingReq, eIDASResponse, spCountry, attrRegistry); + + + // ********************************************************** + // ******* Store resonse infos into session object ********** + // ********************************************************** + + //update MOA-Session data with received information + log.debug("Store eIDAS response information into pending-request."); + AuthProcessDataWrapper authProcessData = pendingReq.getSessionData(AuthProcessDataWrapper.class); + authProcessData.setQAALevel(eIDASResponse.getLevelOfAssurance()); + authProcessData.setGenericDataToSession(Constants.DATA_FULL_EIDAS_RESPONSE, eIDASResponse); + + //store MOA-session to database + requestStoreage.storePendingRequest(pendingReq); + + revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.RESPONSE_FROM_EIDAS_NODE_VALID); + + } catch (EAAFException e) { + revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.RESPONSE_FROM_EIDAS_NODE_NOT_VALID); + throw new TaskExecutionException(pendingReq, "eIDAS Response processing FAILED.", e); + + } catch (Exception e) { + log.warn("eIDAS Response processing FAILED.", e); + revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.RESPONSE_FROM_EIDAS_NODE_NOT_VALID); + throw new TaskExecutionException(pendingReq, e.getMessage(), + new eIDASAuthenticationException("eidas.05", new Object[]{e.getMessage()}, e)); + + } + + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/utils/LoggingHandler.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/utils/LoggingHandler.java new file mode 100644 index 00000000..2f6e7c3a --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/utils/LoggingHandler.java @@ -0,0 +1,52 @@ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.utils; + +import java.io.ByteArrayOutputStream; +import java.util.Set; + +import javax.xml.namespace.QName; +import javax.xml.soap.SOAPMessage; +import javax.xml.ws.handler.MessageContext; +import javax.xml.ws.handler.soap.SOAPHandler; +import javax.xml.ws.handler.soap.SOAPMessageContext; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LoggingHandler implements SOAPHandler { + + Logger log = LoggerFactory.getLogger(LoggingHandler.class); + + public boolean handleMessage(SOAPMessageContext context) { + SOAPMessage msg = context.getMessage(); + boolean request = ((Boolean) context + .get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + try { + if (request) { + msg.writeTo(bos); + } else { // This is the response message + msg.writeTo(bos); + } + + log.trace(bos.toString()); + log.trace(new String(bos.toByteArray())); + + } catch (Exception e) { + log.trace(e.getMessage(), e); + } + return true; + } + + public boolean handleFault(SOAPMessageContext context) { + return handleMessage(context); + } + + public void close(MessageContext context) { + } + + public Set getHeaders() { + return null; + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/utils/eIDASResponseUtils.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/utils/eIDASResponseUtils.java new file mode 100644 index 00000000..6269d242 --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/utils/eIDASResponseUtils.java @@ -0,0 +1,98 @@ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.joda.time.DateTime; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.ImmutableList; + +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.Constants; +import at.gv.egiz.eaaf.core.impl.data.Trible; +import eu.eidas.auth.commons.attribute.AttributeDefinition; +import eu.eidas.auth.commons.attribute.AttributeValue; +import eu.eidas.auth.commons.attribute.AttributeValueMarshaller; +import eu.eidas.auth.commons.attribute.AttributeValueMarshallingException; +import eu.eidas.auth.commons.protocol.eidas.impl.PostalAddress; + +public class eIDASResponseUtils { + private static final Logger log = LoggerFactory.getLogger(eIDASResponseUtils.class); + + public static final String PERSONALIDENIFIER_VALIDATION_PATTERN = "^[A-Z,a-z]{2}/[A-Z,a-z]{2}/.*"; + + /** + * Validate a eIDAS PersonalIdentifier attribute value + * This validation is done according to eIDAS SAML Attribute Profile - Section 2.2.3 Unique Identifier + * + * @param uniqueID eIDAS attribute value of a unique identifier + * @return true if the uniqueID matches to eIDAS to Unique Identifier specification, otherwise false + */ + public static boolean validateEidasPersonalIdentifier(String uniqueID) { + Pattern pattern = Pattern.compile(PERSONALIDENIFIER_VALIDATION_PATTERN ); + Matcher matcher = pattern.matcher(uniqueID); + return matcher.matches(); + + } + + + /** + * Parse an eIDAS PersonalIdentifier attribute value into it components. + * This processing is done according to eIDAS SAML Attribute Profile - Section 2.2.3 Unique Identifier + * + * @param uniqueID eIDAS attribute value of a unique identifier + * @return {@link Trible} that contains: + *
First : citizen country + *
Second: destination country + *
Third : unique identifier + *
or null if the attribute value has a wrong format + */ + public static Trible parseEidasPersonalIdentifier(String uniqueID) { + if (!validateEidasPersonalIdentifier(uniqueID)) { + log.error("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + + " looks wrong formated. Value:" + ((String)uniqueID)); + return null; + + } + return Trible.newInstance(uniqueID.substring(0, 2), uniqueID.substring(3, 5), uniqueID.substring(6)); + + } + + public static List translateStringListAttribute(AttributeDefinition attributeDefinition, ImmutableList> attributeValues) { + final List stringListAttribute = new ArrayList(); + AttributeValueMarshaller attributeValueMarshaller = attributeDefinition.getAttributeValueMarshaller(); + for (AttributeValue attributeValue : attributeValues) { + String valueString = null; + try { + valueString = attributeValueMarshaller.marshal((AttributeValue) attributeValue); + stringListAttribute.add(valueString); + } catch (AttributeValueMarshallingException e) { + throw new IllegalStateException(e); + + } + } + + return stringListAttribute; + + } + + public static DateTime translateDateAttribute(AttributeDefinition attributeDefinition, ImmutableList> attributeValues) { + if (attributeValues.size() != 0) { + final AttributeValue firstAttributeValue = attributeValues.get(0); + return (DateTime) firstAttributeValue.getValue(); + + } + + return null; + } + + public static PostalAddress translateAddressAttribute(AttributeDefinition attributeDefinition, ImmutableList> attributeValues) { + final AttributeValue firstAttributeValue = attributeValues.get(0); + return (PostalAddress) firstAttributeValue.getValue(); + + } + +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java new file mode 100644 index 00000000..4af4e7cf --- /dev/null +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java @@ -0,0 +1,135 @@ +package at.asitplus.eidas.specific.modules.authmodule_eIDASv2.validator; + +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.ImmutableList; + +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.Constants; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASValidationException; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.service.eIDASAttributeRegistry; +import at.asitplus.eidas.specific.modules.authmodule_eIDASv2.utils.eIDASResponseUtils; +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.impl.data.Trible; +import eu.eidas.auth.commons.attribute.AttributeDefinition; +import eu.eidas.auth.commons.attribute.AttributeValue; +import eu.eidas.auth.commons.light.ILightResponse; +import eu.eidas.auth.commons.protocol.eidas.LevelOfAssurance; + +/** + * @author tlenz + * + */ +public class eIDASResponseValidator { + private static final Logger log = LoggerFactory.getLogger(eIDASResponseValidator.class); + + public static void validateResponse(IRequest pendingReq, ILightResponse eIDASResponse, String spCountry, eIDASAttributeRegistry attrRegistry) throws eIDASValidationException { + + /*-----------------------------------------------------| + * validate received LoA against minimum required LoA | + *_____________________________________________________| + */ + LevelOfAssurance respLoA = LevelOfAssurance.fromString(eIDASResponse.getLevelOfAssurance()); + List allowedLoAs = pendingReq.getServiceProviderConfiguration().getRequiredLoA(); + boolean loaValid = false; + for (String allowedLoaString : allowedLoAs) { + LevelOfAssurance allowedLoa = LevelOfAssurance.fromString(allowedLoaString); + if (respLoA.numericValue() >= allowedLoa.numericValue()) { + log.debug("Response contains valid LoA. Resume process ... "); + loaValid = true; + break; + + } else + log.trace("Allowed LoA: " + allowedLoaString + " DOES NOT match response LoA: " + eIDASResponse.getLevelOfAssurance()); + + } + + if (!loaValid) { + log.error("eIDAS Response LevelOfAssurance is lower than the required! " + + "(Resp-LoA:" + respLoA.getValue() + " Req-LoA:" + allowedLoAs.toArray() + ")"); + throw new eIDASValidationException("eidas.06", new Object[]{respLoA.getValue()}); + + } + + + + /*-----------------------------------------------------| + * validate 'PersonalIdentifier' attribute | + *_____________________________________________________| + */ + AttributeDefinition attrDefinition = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); + final ImmutableList> attributeValues = eIDASResponse.getAttributes().getAttributeMap().get(attrDefinition).asList(); + List personalIdObj = eIDASResponseUtils.translateStringListAttribute(attrDefinition, attributeValues); + + //check if attribute exists + if (personalIdObj == null || personalIdObj.isEmpty()) { + log.warn("eIDAS Response include NO 'PersonalIdentifier' attriubte " + + ".... That can be a BIG problem in further processing steps"); + throw new eIDASValidationException("eidas.05", new Object[] {"NO 'PersonalIdentifier' attriubte"}); + + } else if (personalIdObj.size() > 1) { + log.warn("eIDAS Response include MORE THAN ONE 'PersonalIdentifier' attriubtes " + + ".... That can be a BIG problem in further processing steps"); + throw new eIDASValidationException("eidas.05", new Object[] {"MORE THAN ONE 'PersonalIdentifier' attriubtes"}); + + } else { + String natPersId = personalIdObj.get(0); + //validate attribute value format + Trible split = + eIDASResponseUtils.parseEidasPersonalIdentifier(natPersId); + if (split == null) { + throw new eIDASValidationException("eidas.07", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "Wrong identifier format"}); + + } else { + //validation according to eIDAS SAML Attribute Profile, Section 2.2.3 + if (StringUtils.isEmpty(split.getSecond())) { + log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + + " includes NO destination country. Value:" + natPersId); + throw new eIDASValidationException("eidas.07", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "No or empty destination country"}); + + } + if (!split.getSecond().equalsIgnoreCase(spCountry)) { + log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + + " includes wrong destination country. Value:" + natPersId + + " SP-Country:" + spCountry); + throw new eIDASValidationException("eidas.07", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "Destination country does not match to SP country"}); + + } + + if (StringUtils.isEmpty(split.getFirst())) { + log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + + " includes NO citizen country. Value:" + natPersId); + throw new eIDASValidationException("eidas.07", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "No or empty citizen country"}); + + } + if (!split.getSecond().equalsIgnoreCase(spCountry)) { + log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + + " includes a relaying-party country that does not match to service-provider country. " + + " Value:" + natPersId + + " SP Country:" + spCountry); + throw new eIDASValidationException("eidas.07", + new Object[]{ + Constants.eIDAS_ATTR_PERSONALIDENTIFIER, + "Citizen country does not match to eIDAS-node country that generates the response"}); + + } + } + } + + } +} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/Constants.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/Constants.java deleted file mode 100644 index beb3cce7..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/Constants.java +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2; - -import java.net.URI; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import at.gv.egiz.eaaf.core.api.data.EAAFConstants; - -public class Constants { - - public static final String DATA_REQUESTERID = "req_requesterId"; - public static final String DATA_PROVIDERNAME = "req_providerName"; - public static final String DATA_REQUESTED_LOA_LIST = "req_requestedLoA"; - public static final String DATA_REQUESTED_LOA_COMPERISON = "req_requestedLoAComperision"; - public static final String DATA_FULL_EIDAS_RESPONSE = "resp_fulleIDASResponse"; - - - //templates for post-binding forwarding - public static final String TEMPLATE_POST_FORWARD_NAME = "eidas_node_forward.html"; - public static final String TEMPLATE_POST_FORWARD_ENDPOINT = "endPoint"; - public static final String TEMPLATE_POST_FORWARD_TOKEN_NAME = "tokenName"; - public static final String TEMPLATE_POST_FORWARD_TOKEN_VALUE = "tokenValue"; - - - //configuration properties - public static final String CONIG_PROPS_EIDAS_PREFIX="auth.eIDAS"; - public static final String CONIG_PROPS_EIDAS_NODE= CONIG_PROPS_EIDAS_PREFIX + ".node_v2"; - public static final String CONIG_PROPS_EIDAS_NODE_COUNTRYCODE = CONIG_PROPS_EIDAS_NODE + ".countrycode"; - public static final String CONIG_PROPS_EIDAS_NODE_PUBLICSECTOR_TARGETS = CONIG_PROPS_EIDAS_NODE + ".publicSectorTargets"; - public static final String CONIG_PROPS_EIDAS_NODE_ENTITYID = CONIG_PROPS_EIDAS_NODE + ".entityId"; - public static final String CONIG_PROPS_EIDAS_NODE_FORWARD_URL = CONIG_PROPS_EIDAS_NODE + ".forward.endpoint"; - public static final String CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD = CONIG_PROPS_EIDAS_NODE + ".forward.method"; - public static final String CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_ONLYNATURAL = CONIG_PROPS_EIDAS_NODE + ".attributes.requested.onlynatural."; - public static final String CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_REPRESENTATION = CONIG_PROPS_EIDAS_NODE + ".attributes.requested.representation."; - public static final String CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME = CONIG_PROPS_EIDAS_NODE + ".workarounds.addAlwaysProviderName";; - public static final String CONIG_PROPS_EIDAS_NODE_WORKAROUND_USEREQUESTIDASTRANSACTIONIDENTIFIER = CONIG_PROPS_EIDAS_NODE + ".workarounds.useRequestIdAsTransactionIdentifier"; - - public static final String FORWARD_METHOD_POST = "POST"; - public static final String FORWARD_METHOD_GET = "GET"; - - public static final String CONIG_PROPS_EIDAS_SZRCLIENT= CONIG_PROPS_EIDAS_PREFIX + ".szrclient"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_USETESTSERVICE= CONIG_PROPS_EIDAS_SZRCLIENT + ".useTestService"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_TRACEMESSAGES= CONIG_PROPS_EIDAS_SZRCLIENT + ".debug.logfullmessages"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_USEDUMMY= CONIG_PROPS_EIDAS_SZRCLIENT + ".debug.useDummySolution"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_INSERTERNB= CONIG_PROPS_EIDAS_SZRCLIENT + ".debug.insertERnB"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_TIMEOUT_CONNECTION= CONIG_PROPS_EIDAS_SZRCLIENT + ".timeout.connection"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_TIMEOUT_RESPONSE= CONIG_PROPS_EIDAS_SZRCLIENT + ".timeout.response"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_ENDPOINT_PROD= CONIG_PROPS_EIDAS_SZRCLIENT + ".endpoint.prod"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_ENDPOINT_TEST= CONIG_PROPS_EIDAS_SZRCLIENT + ".endpoint.test"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_SSL_KEYSTORE_PATH = CONIG_PROPS_EIDAS_SZRCLIENT + ".ssl.keyStore.path"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_SSL_KEYSTORE_PASSWORD = CONIG_PROPS_EIDAS_SZRCLIENT + ".ssl.keyStore.password"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_SSL_TRUSTSTORE_PATH = CONIG_PROPS_EIDAS_SZRCLIENT + ".ssl.trustStore.path"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_SSL_TRUSTSTORE_PASSWORD = CONIG_PROPS_EIDAS_SZRCLIENT + ".ssl.trustStore.password"; - - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_EDOCUMENTTYPE = CONIG_PROPS_EIDAS_SZRCLIENT + ".params.documenttype"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_VKZ = CONIG_PROPS_EIDAS_SZRCLIENT + ".params.vkz"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_ISSUING_DATE = CONIG_PROPS_EIDAS_SZRCLIENT + ".params.issuingdate"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_ISSUING_AUTHORITY = CONIG_PROPS_EIDAS_SZRCLIENT + ".params.issuingauthority"; - public static final String CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_KEYS_USEDUMMY= CONIG_PROPS_EIDAS_SZRCLIENT + ".params.usedummykeys"; - - //http endpoint descriptions - public static final String eIDAS_HTTP_ENDPOINT_SP_POST = "/eidas/light/sp/post"; - public static final String eIDAS_HTTP_ENDPOINT_SP_REDIRECT = "/eidas/light/sp/redirect"; - public static final String eIDAS_HTTP_ENDPOINT_IDP_COLLEAGUEREQUEST = "/eidas/light/ColleagueRequest"; - public static final String eIDAS_HTTP_ENDPOINT_METADATA = "/eidas/light/metadata"; - - //eIDAS request parameters - public static final String eIDAS_REQ_NAMEID_FORMAT = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"; - - //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 = "FirstName"; - public static final String eIDAS_ATTR_CURRENTFAMILYNAME = "FamilyName"; - public static final String eIDAS_ATTR_LEGALPERSONIDENTIFIER = "LegalPersonIdentifier"; - public static final String eIDAS_ATTR_LEGALNAME = "LegalName"; - - public static final List NATURALPERSONMINIMUMDATASETLIST = Collections.unmodifiableList(new ArrayList() { - private static final long serialVersionUID = 1L; - { - //TODO: find correct location of attribute definitions -// add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.CURRENT_FAMILY_NAME.getNameUri()); -// add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.CURRENT_GIVEN_NAME.getNameUri()); -// add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.DATE_OF_BIRTH.getNameUri()); -// add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.PERSON_IDENTIFIER.getNameUri()); - } - }); - - public static final String POLICY_DEFAULT_ALLOWED_TARGETS = - EAAFConstants.URN_PREFIX_CDID.replaceAll("\\.", "\\\\.").replaceAll("\\+", "\\\\+") + ".*"; - - //SAML2 Constants - public static final String SUCCESS_URI = "urn:oasis:names:tc:SAML:2.0:status:Success"; - - public static final String HTTP_CLIENT_DEFAULT_TIMEOUT_CONNECTION = "30"; //seconds - public static final String HTTP_CLIENT_DEFAULT_TIMEOUT_RESPONSE = "60"; //seconds - - - //Default values for SZR communication - public static final String SZR_CONSTANTS_DEFAULT_DOCUMENT_TYPE = "ELEKTR_DOKUMENT"; - - //TODO remove!!! - public static final String SZR_CONSTANTS_DEFAULT_ISSUING_DATE = "2014-01-01"; - public static final String SZR_CONSTANTS_DEFAULT_ISSUING_AUTHORITY = "ms-specific eIDAS-Node for AT"; - public final static byte[] SZR_CONSTANTS_DEFAULT_PUBL_KEY = new byte[] {48, -127, -97, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0, 3, -127, -115, 0, 48, -127, -119, 2, -127, -127, 0, -106, 114, -113, -1, -84, 116, 35, 3, 70, -81, 81, -110, -10, -59, 114, 4, -109, 86, 127, -50, 125, 47, 4, 80, 79, 53, 117, -36, 15, -16, -61, 110, 39, 89, 29, -43, 37, -127, 80, -109, -38, 65, 125, -119, 44, -111, -21, 47, -98, 38, -112, -24, 107, -110, 17, -10, 51, -4, -36, -72, -28, -18, -14, 117, -67, 76, -31, 32, 92, 104, -21, 68, 31, -12, 30, -104, -104, 42, -107, 126, 84, 50, 85, -117, 44, -100, -4, 102, -100, 52, -68, 77, -32, 9, -16, -30, -104, -90, 107, -88, 7, 97, -94, 72, -61, -40, 80, -112, -65, -25, -72, -19, -95, -54, 31, 15, 24, -105, 123, -81, 23, -123, 92, -103, -101, 47, 47, -105, 2, 3, 1, 0, 1}; - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationModulImpl.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationModulImpl.java deleted file mode 100644 index c41559b8..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationModulImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2; - -import org.apache.commons.lang3.StringUtils; - -import at.gv.egiz.eaaf.core.api.idp.auth.modules.AuthModule; -import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; -import at.gv.egiz.eidas.specific.connector.MSeIDASNodeConstants; - -/** - * @author tlenz - * - */ -public class eIDASAuthenticationModulImpl implements AuthModule { - - private int priority = 1; - - @Override - public int getPriority() { - return priority; - } - - /** - * Sets the priority of this module. Default value is {@code 0}. - * @param priority The priority. - */ - public void setPriority(int priority) { - this.priority = priority; - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#selectProcess(at.gv.egovernment.moa.id.process.api.ExecutionContext) - */ - @Override - public String selectProcess(ExecutionContext context) { - if (StringUtils.isNotBlank((String) context.get(MSeIDASNodeConstants.REQ_PARAM_SELECTED_COUNTRY)) || - StringUtils.isNotBlank((String) context.get(MSeIDASNodeConstants.REQ_PARAM_SELECTED_COUNTRY))) - return "eIDASAuthentication_v2"; - else - return null; - - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getProcessDefinitions() - */ - @Override - public String[] getProcessDefinitions() { - return new String[] { "classpath:eIDAS.Authentication.process.xml" }; - } - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationSpringResourceProvider.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationSpringResourceProvider.java deleted file mode 100644 index e067acfb..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASAuthenticationSpringResourceProvider.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2; - -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; - -import at.gv.egiz.components.spring.api.SpringResourceProvider; - -public class eIDASAuthenticationSpringResourceProvider implements SpringResourceProvider { - - @Override - public String getName() { - return "Auth. module for eIDAS Ref. Impl. v2.x"; - } - - @Override - public String[] getPackagesToScan() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Resource[] getResourcesToLoad() { - ClassPathResource eIDASAuthConfig = new ClassPathResource("/eidas_v2_auth.beans.xml", eIDASAuthenticationSpringResourceProvider.class); - - return new Resource[] {eIDASAuthConfig}; - } - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASSignalServlet.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASSignalServlet.java deleted file mode 100644 index 77f799e7..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/eIDASSignalServlet.java +++ /dev/null @@ -1,131 +0,0 @@ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2; - -import java.io.IOException; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import com.google.common.collect.ImmutableSortedSet; - -import at.gv.egiz.eaaf.core.impl.idp.controller.AbstractProcessEngineSignalController; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASAuthenticationException; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.service.eIDASAttributeRegistry; -import eu.eidas.auth.commons.EidasParameterKeys; -import eu.eidas.auth.commons.light.ILightResponse; -import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames; -import eu.eidas.specificcommunication.exception.SpecificCommunicationException; -import eu.eidas.specificcommunication.protocol.impl.SpecificConnectorCommunicationServiceImpl; - - -/** - * @author tlenz - * - */ -@Controller -public class eIDASSignalServlet extends AbstractProcessEngineSignalController { - - private static final Logger log = LoggerFactory.getLogger(eIDASSignalServlet.class); - @Autowired private ApplicationContext context; - @Autowired private eIDASAttributeRegistry attrRegistry; - - public eIDASSignalServlet() { - super(); - log.debug("Registering servlet " + getClass().getName() + - " with mappings '"+ Constants.eIDAS_HTTP_ENDPOINT_SP_POST + - "' and '"+ Constants.eIDAS_HTTP_ENDPOINT_SP_REDIRECT + "'."); - - } - - @RequestMapping(value = { Constants.eIDAS_HTTP_ENDPOINT_SP_POST, - Constants.eIDAS_HTTP_ENDPOINT_SP_REDIRECT - }, - method = {RequestMethod.POST, RequestMethod.GET}) - public void restoreEidasAuthProcess(HttpServletRequest req, HttpServletResponse resp) throws IOException { - signalProcessManagement(req, resp); - } - - - /** - * Protocol specific implementation to get the pending-requestID - * from http request object - * - * @param request The http Servlet-Request object - * @return The Pending-request id - * - */ - @Override - public String getPendingRequestId(HttpServletRequest request) { - //String sessionId = super.getPendingRequestId(request); - - try { - //get token from Request - final String tokenBase64 = request.getParameter(EidasParameterKeys.TOKEN.toString()); - if (StringUtils.isEmpty(tokenBase64)) { - log.warn("NO eIDAS message token found."); - throw new eIDASAuthenticationException("eidas.04", null); - - } - log.trace("Receive eIDAS-node token: " + tokenBase64 + " Starting transaction-restore process ... "); - - - - final SpecificConnectorCommunicationServiceImpl specificConnectorCommunicationService = - (SpecificConnectorCommunicationServiceImpl) context.getBean(SpecificCommunicationDefinitionBeanNames.SPECIFIC_CONNECTOR_COMMUNICATION_SERVICE.toString()); - ILightResponse eIDASResponse = specificConnectorCommunicationService.getAndRemoveResponse(tokenBase64, - ImmutableSortedSet.copyOf(attrRegistry.getCoreAttributeRegistry().getAttributes())); - - String pendingReqId = null; - if (StringUtils.isEmpty(eIDASResponse.getRelayState())) { - log.debug("eIDAS Node returns no RelayState. "); - - if (authConfig.getBasicMOAIDConfigurationBoolean( - Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_USEREQUESTIDASTRANSACTIONIDENTIFIER, - false)) { - log.trace("Use lightRequestId to recover session ... "); - pendingReqId = transactionStorage.get(eIDASResponse.getInResponseToId(), String.class); - if (StringUtils.isNotEmpty(pendingReqId)) { - log.debug("Restoring session with lightRequestId ... "); - transactionStorage.remove(eIDASResponse.getInResponseToId()); - - } - } - - } else { - log.debug("Find transaction identifier in SAML2 'RelayState': " + eIDASResponse.getRelayState()); - pendingReqId = eIDASResponse.getRelayState(); - - } - - if (StringUtils.isNotEmpty(pendingReqId)) { - request.setAttribute(Constants.DATA_FULL_EIDAS_RESPONSE, eIDASResponse); - return pendingReqId; - - } - - log.info("NO transaction identifier found! Stopping process ...."); - log.trace("FullResponse: " + eIDASResponse.toString()); - - } catch (SpecificCommunicationException e) { - log.warn("Can NOT load eIDAS Response from cache.", e); - log.debug("eIDAS response token was: " + request.getParameter(EidasParameterKeys.TOKEN.toString())); - - } catch (Exception e) { - log.warn("Unable to retrieve moa session id.", e); - - } - - return null; - } - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/SZRCommunicationException.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/SZRCommunicationException.java deleted file mode 100644 index a0c3cf88..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/SZRCommunicationException.java +++ /dev/null @@ -1,15 +0,0 @@ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.exception; - -public class SZRCommunicationException extends eIDASAuthenticationException { - - private static final long serialVersionUID = 1L; - - public SZRCommunicationException(String internalMsgId, Object[] params) { - super(internalMsgId, params); - } - - public SZRCommunicationException(String internalMsgId, Object[] params, Throwable e) { - super(internalMsgId, params, e); - } - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAttributeException.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAttributeException.java deleted file mode 100644 index f1d4280f..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAttributeException.java +++ /dev/null @@ -1,15 +0,0 @@ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.exception; - -public class eIDASAttributeException extends eIDASAuthenticationException { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public eIDASAttributeException(String attrbuteName) { - super("eidas.00", new Object[] {attrbuteName}); - - } - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAuthenticationException.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAuthenticationException.java deleted file mode 100644 index 939e7471..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASAuthenticationException.java +++ /dev/null @@ -1,20 +0,0 @@ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.exception; - -import at.gv.egiz.eaaf.core.exceptions.EAAFAuthenticationException; - -public class eIDASAuthenticationException extends EAAFAuthenticationException{ - - /** - * - */ - private static final long serialVersionUID = 1L; - - public eIDASAuthenticationException(String internalMsgId, Object[] params) { - super(internalMsgId, params); - } - - public eIDASAuthenticationException(String internalMsgId, Object[] params, Throwable e) { - super(internalMsgId, params, e); - } - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASValidationException.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASValidationException.java deleted file mode 100644 index 7b81eacd..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/exception/eIDASValidationException.java +++ /dev/null @@ -1,14 +0,0 @@ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.exception; - -public class eIDASValidationException extends eIDASAuthenticationException { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public eIDASValidationException(String internalMsgId, Object[] params) { - super(internalMsgId, params); - } - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/service/eIDASAttributeRegistry.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/service/eIDASAttributeRegistry.java deleted file mode 100644 index 2bb3e0b0..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/service/eIDASAttributeRegistry.java +++ /dev/null @@ -1,115 +0,0 @@ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.service; - -import java.io.File; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.PostConstruct; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; -import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.Constants; -import eu.eidas.auth.commons.attribute.AttributeRegistries; -import eu.eidas.auth.commons.attribute.AttributeRegistry; - -@Service("attributeRegistry") -public class eIDASAttributeRegistry { - private static final Logger log = LoggerFactory.getLogger(eIDASAttributeRegistry.class); - @Autowired private IConfiguration basicConfig; - - private AttributeRegistry coreAttributeRegistry; - - private String eidasAttributesFile; - private String additionalAttributesFile; - - @PostConstruct - private void initialize() throws RuntimeException { - try { - if (eidasAttributesFile.isEmpty()) { - log.error("Basic eIDAS addribute definition NOT defined"); - throw new EAAFConfigurationException("config.30", - new Object[] {"eidas-attributes.xml"}); - - } - - boolean additionalAttrAvailabe = false; - if (!additionalAttributesFile.isEmpty()) { - File file = new File(additionalAttributesFile); - if (file.exists()) - additionalAttrAvailabe = true; - - } - - if (!additionalAttrAvailabe) { - log.info("Start eIDAS ref. impl. Core without additional eIDAS attribute definitions ... "); - coreAttributeRegistry = AttributeRegistries.fromFiles(eidasAttributesFile, null); - - } else { - //load attribute definitions - log.info("Start eIDAS ref. impl. Core with additional eIDAS attribute definitions ... "); - coreAttributeRegistry = AttributeRegistries.fromFiles(eidasAttributesFile, null, additionalAttributesFile); - - } - - } catch (Throwable e) { - log.error("Can NOT initialize eIDAS attribute definition." , e); - new RuntimeException("Can NOT initialize eIDAS attribute definition.", e); - - } - } - - - public AttributeRegistry getCoreAttributeRegistry() { - return coreAttributeRegistry; - } - - public Map getAttributeSetFromConfiguration() { - Map result = new HashMap(); - - /*TODO: select set for representation if mandates should be used. - * It's an open task in respect to requested eIDAS attributes and isRequired flag, - * because there can be a decision problem in case of natural or legal person representation! - * From an Austrian use-case point of view, an Austrian service provider can support mandates for - * natural and legal persons at the same time. However, we CAN NOT request attributes for natural AND - * legal persons on the same time, because it's not possible to represent both simultaneously. - */ - Map configAttributes = - basicConfig.getBasicMOAIDConfigurationWithPrefix( - Constants.CONIG_PROPS_EIDAS_NODE_ATTRIBUTES_REQUESTED_ONLYNATURAL); - for (String el: configAttributes.values()) { - if (StringUtils.isNotEmpty(el.trim())) { - List attrDef = KeyValueUtils.getListOfCSVValues(el.trim()); - boolean isRequired = false; - if (attrDef.size() == 2) - isRequired = Boolean.parseBoolean(attrDef.get(1)); - - result.put(attrDef.get(0), isRequired); - - } - } - - log.trace("Load #" + result.size() + " requested attributes from configuration"); - return result; - - } - - - public void setEidasAttributesFile(String eidasAttributesFile) { - this.eidasAttributesFile = eidasAttributesFile; - } - - public void setAdditionalAttributesFile(String additionalAttributesFile) { - this.additionalAttributesFile = additionalAttributesFile; - } - - -} - diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/szr/SZRClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/szr/SZRClient.java deleted file mode 100644 index 86f0d0bb..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/szr/SZRClient.java +++ /dev/null @@ -1,372 +0,0 @@ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.szr; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.net.URL; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.UnrecoverableKeyException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.annotation.PostConstruct; -import javax.annotation.Resource; -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; -import javax.xml.namespace.QName; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; -import javax.xml.ws.BindingProvider; -import javax.xml.ws.Dispatch; -import javax.xml.ws.WebServiceContext; -import javax.xml.ws.handler.Handler; - -import org.apache.commons.lang3.StringUtils; -import org.apache.cxf.configuration.jsse.TLSClientParameters; -import org.apache.cxf.endpoint.Client; -import org.apache.cxf.frontend.ClientProxy; -import org.apache.cxf.jaxws.DispatchImpl; -import org.apache.cxf.transport.http.HTTPConduit; -import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; -import org.apache.xpath.XPathAPI; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.w3._2000._09.xmldsig.KeyValueType; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -import at.gv.egiz.eaaf.core.api.data.XMLNamespaceConstants; -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.impl.utils.DOMUtils; -import at.gv.egiz.eaaf.core.impl.utils.FileUtils; -import at.gv.egiz.eaaf.core.impl.utils.KeyStoreUtils; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.Constants; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.exception.SZRCommunicationException; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.utils.LoggingHandler; -import szrservices.GetBPK; -import szrservices.GetBPKResponse; -import szrservices.GetIdentityLink; -import szrservices.GetIdentityLinkResponse; -import szrservices.IdentityLinkType; -import szrservices.PersonInfoType; -import szrservices.SZR; -import szrservices.SZRException_Exception; - -@Service("SZRClientForeIDAS") -public class SZRClient { - private static final Logger log = LoggerFactory.getLogger(SZRClient.class); - - private static final String CLIENT_DEFAULT = "DefaultClient"; - private static final String CLIENT_RAW = "RawClient"; - - @Autowired private IConfiguration basicConfig; - @Resource private WebServiceContext wsContext; - - //client for anything, without identitylink - private SZR szr = null; - - //RAW client is needed for identitylink - private Dispatch dispatch = null; - - - private SZRService szrService = null; - private String szrURL = null; - private QName qname = null; - - public IdentityLinkType getIdentityLink(PersonInfoType personInfo, List keyValue, Boolean insertERnP) throws SZRCommunicationException { - try { - return szr.getIdentityLink( - personInfo, - keyValue, - insertERnP); - - } catch (SZRException_Exception e) { - log.warn("SZR communication FAILED. Reason: " + e.getMessage(), e); - throw new SZRCommunicationException("ernb.02", new Object[] {e.getMessage()}, e); - - } - - } - - public IdentityLinkType getIdentityLinkInRawMode(PersonInfoType personInfo, List keyValue, Boolean insertERnP) throws SZRCommunicationException { - try { - GetIdentityLink getIDL = new GetIdentityLink(); - getIDL.setInsertERnP(insertERnP); - getIDL.setPersonInfo(personInfo); - getIDL.getKeyValue().addAll(keyValue); - - JAXBContext jaxbContext = JAXBContext.newInstance(GetIdentityLink.class); - Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); - - final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - jaxbMarshaller.marshal(getIDL, outputStream); - outputStream.flush(); - - Source source = new StreamSource(new ByteArrayInputStream(outputStream.toByteArray())); - outputStream.close(); - - log.trace("Requesting SZR ... "); - Source response = dispatch.invoke(source); - log.trace("Receive RAW response from SZR"); - - byte[] szrResponse = sourceToByteArray(response); - JAXBContext ctx = JAXBContext.newInstance(IdentityLinkType.class - .getPackage().getName()); - GetIdentityLinkResponse jaxbElement = (GetIdentityLinkResponse) ctx - .createUnmarshaller().unmarshal(new ByteArrayInputStream(szrResponse)); - - - //build response - log.trace(new String(szrResponse)); - log.trace("Signature successfully created. Extracting from MOA-SS container."); - - // ok, we have success - Document doc = DOMUtils.parseDocument( - new ByteArrayInputStream(szrResponse), - true, XMLNamespaceConstants.ALL_SCHEMA_LOCATIONS, null, null - ); - String xpathExpression = "//saml:Assertion"; - Element nsNode = doc.createElementNS("urn:oasis:names:tc:SAML:1.0:assertion", "saml:NSNode"); - - log.trace("Selecting signed doc " + xpathExpression); - Element documentNode = (Element) XPathAPI.selectSingleNode(doc, - xpathExpression, nsNode); - log.trace("Signed document: " + DOMUtils.serializeNode(documentNode)); - - - IdentityLinkType idl = new IdentityLinkType(); - idl.setAssertion(documentNode); - idl.setPersonInfo(jaxbElement.getGetIdentityLinkReturn().getPersonInfo()); - - return idl; - - - //IdentityLinkType idlResp = this.szr.getIdentityLink(personInfo, keyValue, insertERnP); - - } catch ( Exception e) { - log.warn("SZR communication FAILED. Reason: " + e.getMessage(), e); - throw new SZRCommunicationException("ernb.02", new Object[] {e.getMessage()}, e); - - } - - } - - public String getBPK(PersonInfoType personInfo, String target, String vkz) throws SZRCommunicationException { - try { - GetBPK parameters = new GetBPK(); - parameters.setPersonInfo(personInfo); - parameters.setBereichsKennung(target); - parameters.setVKZ(vkz); - GetBPKResponse result = this.szr.getBPK(parameters); - - return result.getGetBPKReturn(); - - } catch (SZRException_Exception e) { - log.warn("SZR communication FAILED. Reason: " + e.getMessage(), e); - throw new SZRCommunicationException("ernb.02", new Object[] {e.getMessage()}, e); - - } - - } - - - @PostConstruct - private void initialize() { - log.info("Starting SZR-Client initialization .... "); - URL url = SZRClient.class.getResource("/szr_client/SZR-1.WSDL"); - - boolean useTestSZR = basicConfig.getBasicMOAIDConfigurationBoolean( - Constants.CONIG_PROPS_EIDAS_SZRCLIENT_USETESTSERVICE, - true); - - if (useTestSZR) { - log.debug("Initializing SZR test environment configuration."); - qname = SZRService.SZRTestumgebung; - szrService = new SZRService(url, new QName("urn:SZRServices", "SZRService")); - szr = szrService.getSZRTestumgebung(); - szrURL = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_ENDPOINT_TEST); - - - } else { - log.debug("Initializing SZR productive configuration."); - qname = SZRService.SZRProduktionsumgebung; - szrService = new SZRService(url, new QName("urn:SZRServices", "SZRService")); - szr = szrService.getSZRProduktionsumgebung(); - szrURL = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_ENDPOINT_PROD); - - } - - //create raw client; - dispatch = szrService.createDispatch(qname, Source.class, javax.xml.ws.Service.Mode.PAYLOAD); - - if (StringUtils.isEmpty(szrURL)) { - log.error("No SZR service-URL found. SZR-Client initalisiation failed."); - throw new RuntimeException("No SZR service URL found. SZR-Client initalisiation failed."); - - } - - log.info("Use SZR service-URL: " + szrURL); - injectBindingProvider((BindingProvider) szr, CLIENT_DEFAULT); - injectBindingProvider((BindingProvider) dispatch, CLIENT_RAW); - - log.debug("Inject HTTP client settings ... "); - injectHTTPClient(szr, CLIENT_DEFAULT); - injectHTTPClient(dispatch, CLIENT_RAW); - - log.info("SZR-Client initialization successfull"); - } - - private void injectHTTPClient(Object raw, String clientType) { - //extract client from implementation - Client client = null; - if (raw instanceof DispatchImpl) - client = ((DispatchImpl)raw).getClient(); - else if (raw instanceof Client) - client = ClientProxy.getClient(raw); - else - throw new RuntimeException("SOAP Client for SZR connection is of UNSUPPORTED type: " + raw.getClass().getName()); - - //set basic connection policies - HTTPConduit http = (HTTPConduit) client.getConduit(); - - //set timeout policy - HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); - httpClientPolicy.setConnectionTimeout( - Integer.parseInt(basicConfig.getBasicConfiguration( - Constants.CONIG_PROPS_EIDAS_SZRCLIENT_TIMEOUT_CONNECTION, - Constants.HTTP_CLIENT_DEFAULT_TIMEOUT_CONNECTION)) * 1000); - httpClientPolicy.setReceiveTimeout( - Integer.parseInt(basicConfig.getBasicConfiguration( - Constants.CONIG_PROPS_EIDAS_SZRCLIENT_TIMEOUT_RESPONSE, - Constants.HTTP_CLIENT_DEFAULT_TIMEOUT_RESPONSE)) * 1000); - http.setClient(httpClientPolicy); - - //inject SSL context in case of https - if (szrURL.toLowerCase().startsWith("https")) { - log.debug("Adding SSLContext to client: " + clientType +" ... "); - TLSClientParameters tlsParams = new TLSClientParameters(); - tlsParams.setSSLSocketFactory(createSSLContext(clientType).getSocketFactory()); - http.setTlsClientParameters(tlsParams ); - log.info("SSLContext initialized for client: " + clientType); - - } - - } - - private void injectBindingProvider(BindingProvider bindingProvider, String clientType) { - Map requestContext = bindingProvider.getRequestContext(); - requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, szrURL); - - log.trace("Adding JAX-WS request/response trace handler to client: " + clientType); - List handlerList = bindingProvider.getBinding().getHandlerChain(); - if (handlerList == null) { - handlerList = new ArrayList(); - bindingProvider.getBinding().setHandlerChain(handlerList); - - } - - //add logging handler to trace messages if required - if (basicConfig.getBasicMOAIDConfigurationBoolean( - Constants.CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_TRACEMESSAGES, - false)) { - LoggingHandler loggingHandler = new LoggingHandler(); - handlerList.add(loggingHandler); - - } - } - - private SSLContext createSSLContext(String clientType) { - try { - SSLContext context = SSLContext.getInstance("TLS"); - - //initialize key-mangager for SSL client-authentication - KeyManager[] keyManager = null; - String keyStorePath = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_SSL_KEYSTORE_PATH); - String keyStorePassword = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_SSL_KEYSTORE_PASSWORD); - if (StringUtils.isNotEmpty(keyStorePath)) { - log.trace("Find keyStore path: " + keyStorePath + " Injecting SSL client certificate ... "); - try { - KeyStore keyStore = KeyStoreUtils.loadKeyStore( - FileUtils.makeAbsoluteURL(keyStorePath, basicConfig.getConfigurationRootDirectory()), - keyStorePassword); - - KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - kmf.init(keyStore, keyStorePassword.toCharArray()); - keyManager = kmf.getKeyManagers(); - log.debug("SSL client certificate injected to client: " + clientType); - - } catch (KeyStoreException | IOException | UnrecoverableKeyException e) { - log.error("Can NOT load SSL client certificate from path: " + keyStorePath); - throw new RuntimeException("Can NOT load SSL client certificate from path: " + keyStorePath, e); - - } - } - - - //initialize SSL TrustStore - TrustManager[] trustManager = null; - String trustStorePath = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_SSL_TRUSTSTORE_PATH); - String trustStorePassword = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_SZRCLIENT_SSL_TRUSTSTORE_PASSWORD); - if (StringUtils.isNotEmpty(trustStorePath)) { - log.trace("Find trustStore path: " + trustStorePath + " Injecting SSL TrustStore ... "); - try { - KeyStore trustStore = KeyStoreUtils.loadKeyStore( - FileUtils.makeAbsoluteURL(trustStorePath, basicConfig.getConfigurationRootDirectory()), - trustStorePassword); - - TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - tmf.init(trustStore); - trustManager = tmf.getTrustManagers(); - log.debug("SSL TrustStore injected to client: " + clientType); - - } catch (KeyStoreException | IOException e) { - log.error("Can NOT open SSL TrustStore from path: " + trustStorePath); - throw new RuntimeException("Can NOT open SSL TrustStore from path: " + trustStorePath, e); - - } - - } - - - context.init(keyManager, trustManager, new SecureRandom()); - return context; - - } catch (NoSuchAlgorithmException | KeyManagementException e) { - log.error("SSLContext initialization FAILED.", e); - throw new RuntimeException("SSLContext initialization FAILED.", e); - - } - - } - - private byte[] sourceToByteArray(Source result) throws TransformerException { - TransformerFactory factory = TransformerFactory.newInstance(); - Transformer transformer = factory.newTransformer(); - transformer.setOutputProperty("omit-xml-declaration", "yes"); - transformer.setOutputProperty("method", "xml"); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - StreamResult streamResult = new StreamResult(); - streamResult.setOutputStream(out); - transformer.transform(result, streamResult); - return out.toByteArray(); - } - - - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/szr/SZRService.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/szr/SZRService.java deleted file mode 100644 index 8e4911b9..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/szr/SZRService.java +++ /dev/null @@ -1,139 +0,0 @@ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.szr; - -import java.net.URL; - -import javax.xml.namespace.QName; -import javax.xml.ws.Service; -import javax.xml.ws.WebEndpoint; -import javax.xml.ws.WebServiceClient; -import javax.xml.ws.WebServiceFeature; - -import szrservices.SZR; - -/** - * This class was generated by Apache CXF 3.1.16 - * 2018-07-10T09:36:01.466+02:00 - * Generated source version: 3.1.16 - * - */ -@WebServiceClient(name = "SZRService", - wsdlLocation = "./src/main/resources/szr_client/SZR-1.WSDL", - targetNamespace = "urn:SZRServices") -public class SZRService extends Service { - - public final static URL WSDL_LOCATION; - - public final static QName SERVICE = new QName("urn:SZRServices", "SZRService"); - public final static QName SZRProduktionsumgebung = new QName("urn:SZRServices", "SZRProduktionsumgebung"); - public final static QName SZRTestumgebung = new QName("urn:SZRServices", "SZRTestumgebung"); - public final static QName SZRBusinesspartnerTestumgebung = new QName("urn:SZRServices", "SZRBusinesspartnerTestumgebung"); - static { - URL url = SZRService.class.getResource("./src/main/resources/szr_client/SZR-1.WSDL"); - if (url == null) { - url = SZRService.class.getClassLoader().getResource("/szr_client/SZR-1.WSDL"); - } - if (url == null) { - java.util.logging.Logger.getLogger(SZRService.class.getName()) - .log(java.util.logging.Level.INFO, - "Can not initialize the default wsdl from {0}", "/szr_client/SZR-1.WSDL"); - } - WSDL_LOCATION = url; - - } - - public SZRService(URL wsdlLocation) { - super(wsdlLocation, SERVICE); - } - - public SZRService(URL wsdlLocation, QName serviceName) { - super(wsdlLocation, serviceName); - } - - public SZRService() { - super(WSDL_LOCATION, SERVICE); - } - - public SZRService(WebServiceFeature ... features) { - super(WSDL_LOCATION, SERVICE, features); - } - - public SZRService(URL wsdlLocation, WebServiceFeature ... features) { - super(wsdlLocation, SERVICE, features); - } - - public SZRService(URL wsdlLocation, QName serviceName, WebServiceFeature ... features) { - super(wsdlLocation, serviceName, features); - } - - - - - /** - * - * @return - * returns SZR - */ - @WebEndpoint(name = "SZRProduktionsumgebung") - public SZR getSZRProduktionsumgebung() { - return super.getPort(SZRProduktionsumgebung, SZR.class); - } - - /** - * - * @param features - * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. - * @return - * returns SZR - */ - @WebEndpoint(name = "SZRProduktionsumgebung") - public SZR getSZRProduktionsumgebung(WebServiceFeature... features) { - return super.getPort(SZRProduktionsumgebung, SZR.class, features); - } - - - /** - * - * @return - * returns SZR - */ - @WebEndpoint(name = "SZRTestumgebung") - public SZR getSZRTestumgebung() { - return super.getPort(SZRTestumgebung, SZR.class); - } - - /** - * - * @param features - * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. - * @return - * returns SZR - */ - @WebEndpoint(name = "SZRTestumgebung") - public SZR getSZRTestumgebung(WebServiceFeature... features) { - return super.getPort(SZRTestumgebung, SZR.class, features); - } - - - /** - * - * @return - * returns SZR - */ - @WebEndpoint(name = "SZRBusinesspartnerTestumgebung") - public SZR getSZRBusinesspartnerTestumgebung() { - return super.getPort(SZRBusinesspartnerTestumgebung, SZR.class); - } - - /** - * - * @param features - * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. - * @return - * returns SZR - */ - @WebEndpoint(name = "SZRBusinesspartnerTestumgebung") - public SZR getSZRBusinesspartnerTestumgebung(WebServiceFeature... features) { - return super.getPort(SZRBusinesspartnerTestumgebung, SZR.class, features); - } - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java deleted file mode 100644 index 8766783f..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/CreateIdentityLinkTask.java +++ /dev/null @@ -1,380 +0,0 @@ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.tasks; - -import java.io.InputStream; -import java.math.BigInteger; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.util.Base64Utils; -import org.w3._2000._09.xmldsig.KeyValueType; -import org.w3._2000._09.xmldsig.RSAKeyValueType; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - -import at.gv.e_government.reference.namespace.persondata._20020228.PersonNameType; -import at.gv.e_government.reference.namespace.persondata._20020228.PhysicalPersonType; -import at.gv.egiz.eaaf.core.api.data.EAAFConstants; -import at.gv.egiz.eaaf.core.api.data.PVPAttributeDefinitions; -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; -import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; -import at.gv.egiz.eaaf.core.exceptions.EAAFException; -import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; -import at.gv.egiz.eaaf.core.impl.data.Pair; -import at.gv.egiz.eaaf.core.impl.data.Trible; -import at.gv.egiz.eaaf.core.impl.idp.auth.builder.BPKBuilder; -import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper; -import at.gv.egiz.eaaf.core.impl.idp.auth.data.SimpleIdentityLinkAssertionParser; -import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; -import at.gv.egiz.eaaf.core.impl.utils.DOMUtils; -import at.gv.egiz.eaaf.core.impl.utils.XPathUtils; -import at.gv.egiz.eidas.specific.connector.MSConnectorEventCodes; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.Constants; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.exception.SZRCommunicationException; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASAttributeException; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.szr.SZRClient; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.utils.eIDASResponseUtils; -import eu.eidas.auth.commons.attribute.AttributeDefinition; -import eu.eidas.auth.commons.attribute.AttributeValue; -import eu.eidas.auth.commons.light.ILightResponse; -import eu.eidas.auth.commons.protocol.eidas.impl.PostalAddress; -import szrservices.IdentityLinkType; -import szrservices.PersonInfoType; -import szrservices.TravelDocumentType; - -/** - * @author tlenz - * - */ -@Component("CreateIdentityLinkTask") -public class CreateIdentityLinkTask extends AbstractAuthServletTask { - private static final Logger log = LoggerFactory.getLogger(CreateIdentityLinkTask.class); - - //@Autowired private eIDASAttributeRegistry attrRegistry; - @Autowired private IConfiguration basicConfig; - @Autowired private SZRClient szrClient; - - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ - @Override - public void execute(ExecutionContext executionContext, - HttpServletRequest request, HttpServletResponse response) - throws TaskExecutionException { - try{ - AuthProcessDataWrapper authProcessData = pendingReq.getSessionData(AuthProcessDataWrapper.class); - ILightResponse eIDASResponse = authProcessData.getGenericDataFromSession( - Constants.DATA_FULL_EIDAS_RESPONSE, ILightResponse.class); - Map simpleAttrMap = converteIDASAttrToSimpleMap(eIDASResponse.getAttributes().getAttributeMap()); - - IIdentityLink identityLink = null; - String bPK = null; - - //extract attributes - Object eIdentifierObj = simpleAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER); - Object familyNameObj = simpleAttrMap.get(Constants.eIDAS_ATTR_CURRENTFAMILYNAME); - Object givenNameObj = simpleAttrMap.get(Constants.eIDAS_ATTR_CURRENTGIVENNAME); - Object dateOfBirthObj = simpleAttrMap.get(Constants.eIDAS_ATTR_DATEOFBIRTH); - - //check if availabe - if (eIdentifierObj == null || !(eIdentifierObj instanceof String)) - throw new eIDASAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER); - - if (familyNameObj == null || !(familyNameObj instanceof String)) - throw new eIDASAttributeException(Constants.eIDAS_ATTR_CURRENTFAMILYNAME); - - if (givenNameObj == null || !(givenNameObj instanceof String)) - throw new eIDASAttributeException(Constants.eIDAS_ATTR_CURRENTGIVENNAME); - - if (dateOfBirthObj == null || !(dateOfBirthObj instanceof DateTime)) - throw new eIDASAttributeException(Constants.eIDAS_ATTR_DATEOFBIRTH); - - //connect SZR-Gateway - if(basicConfig.getBasicMOAIDConfigurationBoolean( - Constants.CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_USEDUMMY, false)) { - log.warn("SZR-Dummy IS ACTIVE! IdentityLink is NOT VALID!!!!"); - // create fake IdL - // - fetch IdL template from resources - InputStream s = CreateIdentityLinkTask.class.getResourceAsStream("/resources/xmldata/fakeIdL_IdL_template.xml"); - Element idlTemplate = DOMUtils.parseXmlValidating(s); - - identityLink = new SimpleIdentityLinkAssertionParser(idlTemplate).parseIdentityLink(); - - // replace data - Element idlassertion = identityLink.getSamlAssertion(); - - // - set fake baseID; - Node prIdentification = XPathUtils.selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH); - prIdentification.getFirstChild().setNodeValue((String) eIdentifierObj); - - //build personal identifier which looks like a baseID -// String fakeBaseID = new BPKBuilder().buildBPK(eIdentifier, "baseID"); -// Logger.info("Map eIDAS eIdentifier:" + eIdentifier + " to fake baseID:" + fakeBaseID); -// prIdentification.getFirstChild().setNodeValue(fakeBaseID); - - // - set last name - Node prFamilyName = XPathUtils.selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_FAMILY_NAME_XPATH); - prFamilyName.getFirstChild().setNodeValue((String) familyNameObj); - - // - set first name - Node prGivenName = XPathUtils.selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_GIVEN_NAME_XPATH); - prGivenName.getFirstChild().setNodeValue((String) givenNameObj); - - // - set date of birth - Node prDateOfBirth = XPathUtils.selectSingleNode(idlassertion, SimpleIdentityLinkAssertionParser.PERSON_DATE_OF_BIRTH_XPATH); - String formatedDateOfBirth = new SimpleDateFormat("yyyy-MM-dd").format(((DateTime)dateOfBirthObj).toDate()); - prDateOfBirth.getFirstChild().setNodeValue(formatedDateOfBirth); - - identityLink = new SimpleIdentityLinkAssertionParser(idlassertion).parseIdentityLink(); - - Pair bPKCalc = new BPKBuilder().generateAreaSpecificPersonIdentifier( - identityLink.getIdentificationValue(), - identityLink.getIdentificationType(), - pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier()); - bPK = bPKCalc.getFirst(); - - - } else { - //contact SZR Gateway - log.debug("Starting connecting SZR Gateway"); - PersonInfoType personInfo = new PersonInfoType(); - PersonNameType personName = new PersonNameType(); - PhysicalPersonType naturalPerson = new PhysicalPersonType(); - TravelDocumentType eDocument = new TravelDocumentType(); - - naturalPerson.setName(personName ); - personInfo.setPerson(naturalPerson ); - personInfo.setTravelDocument(eDocument ); - - //parse some eID attributes - String dateOfBirth = new SimpleDateFormat("yyyy-MM-dd").format(((DateTime)dateOfBirthObj).toDate()); - Trible eIdentifier = - eIDASResponseUtils.parseEidasPersonalIdentifier((String)eIdentifierObj); - String uniqueId = (String)eIdentifierObj; - String citizenCountry = eIdentifier.getFirst(); - - //person information - personName.setFamilyName((String)familyNameObj); - personName.setGivenName((String)givenNameObj); - naturalPerson.setDateOfBirth(dateOfBirth); - eDocument.setIssuingCountry(citizenCountry); - eDocument.setDocumentNumber(uniqueId); - - //eID document information - eDocument.setDocumentType(basicConfig.getBasicConfiguration( - Constants.CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_EDOCUMENTTYPE, - Constants.SZR_CONSTANTS_DEFAULT_DOCUMENT_TYPE)); - - //TODO: that should be removed - eDocument.setIssueDate(basicConfig.getBasicConfiguration( - Constants.CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_ISSUING_DATE, - Constants.SZR_CONSTANTS_DEFAULT_ISSUING_DATE)); - eDocument.setIssuingAuthority(basicConfig.getBasicConfiguration( - Constants.CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_ISSUING_AUTHORITY, - Constants.SZR_CONSTANTS_DEFAULT_ISSUING_AUTHORITY)); - - //TODO: keys are not available in eIDAS - List keyValue = dummyCodeForKeys(); - - /*TODO: - * Validate if IDL signature is valid after using this method - * MAYBE we had to switch to 'getIdentityLinkInRawMode' method! - */ - IdentityLinkType result = szrClient.getIdentityLink( - personInfo, - keyValue, - basicConfig.getBasicMOAIDConfigurationBoolean( - Constants.CONIG_PROPS_EIDAS_SZRCLIENT_DEBUG_INSERTERNB, - true) - ); - - Element idlFromSZR = (Element)result.getAssertion(); - identityLink = new SimpleIdentityLinkAssertionParser(idlFromSZR).parseIdentityLink(); - - - //get bPK from SZR - bPK = szrClient.getBPK( - personInfo, - pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier(), - basicConfig.getBasicConfiguration( - Constants.CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_VKZ, - "no VKZ defined")); - - } - - if (identityLink == null) { - log.error("ERnB did not return an identity link."); - throw new SZRCommunicationException("ernb.00", null); - - } - revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.SZR_IDL_RECEIVED); - - - if (bPK == null) { - log.error("ERnB did not return a bPK for target: " + pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier()); - throw new SZRCommunicationException("ernb.01", null); - - } - revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.SZR_BPK_RECEIVED); - - log.debug("ERnB communication was successfull"); - - authProcessData.setForeigner(true); - authProcessData.setIdentityLink(identityLink); - authProcessData.setGenericDataToSession( - PVPAttributeDefinitions.EID_ISSUING_NATION_NAME, - eIDASResponseUtils.parseEidasPersonalIdentifier((String) simpleAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER)).getFirst()); - - //set bPK and bPKType into auth session - authProcessData.setGenericDataToSession( - PVPAttributeDefinitions.BPK_NAME, - extendBPKbyPrefix( - bPK, - pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier()) - ); - authProcessData.setGenericDataToSession( - PVPAttributeDefinitions.EID_SECTOR_FOR_IDENTIFIER_NAME, - pendingReq.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier()); - - - - //store pending-request - requestStoreage.storePendingRequest(pendingReq); - - } catch (eIDASAttributeException e) { - throw new TaskExecutionException(pendingReq, "Minimum required eIDAS attributeset not found.", e); - - } catch (EAAFException e) { - throw new TaskExecutionException(pendingReq, "IdentityLink generation for foreign person FAILED.", e); - - } catch (Exception e) { - log.error("IdentityLink generation for foreign person FAILED.", e); - throw new TaskExecutionException(pendingReq, "IdentityLink generation for foreign person FAILED.", e); - - } - } - - private List dummyCodeForKeys() { - if (basicConfig.getBasicMOAIDConfigurationBoolean( - Constants.CONIG_PROPS_EIDAS_SZRCLIENT_PARAMS_KEYS_USEDUMMY, - false)) { - List keyvalueList = new ArrayList(); - try { - PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Constants.SZR_CONSTANTS_DEFAULT_PUBL_KEY); - KeyFactory kf = KeyFactory.getInstance("RSA"); - - PublicKey pb = kf.generatePublic(spec); - - RSAPublicKey rsapb = (RSAPublicKey)pb; - BigInteger modulus = rsapb.getModulus(); - BigInteger exponent = rsapb.getPublicExponent(); - - // set key values - RSAKeyValueType rsa = new RSAKeyValueType(); - rsa.setExponent(new String(Base64Utils.encode(exponent.toByteArray()))); - rsa.setModulus(new String(Base64Utils.encode(modulus.toByteArray()))); - - KeyValueType key = new KeyValueType(); - key.setRSAKeyValue(rsa); - - keyvalueList.add(key); - - return keyvalueList; - } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { - log.error("TestCode has an internal ERROR", e); - - } - - } - - return null; - - } - - private String extendBPKbyPrefix(String bpk, String type) { - String bPKType = null; - - if (type.startsWith(EAAFConstants.URN_PREFIX_WBPK)) - bPKType = type.substring((EAAFConstants.URN_PREFIX_WBPK).length()); - - else if (type.startsWith(EAAFConstants.URN_PREFIX_CDID)) - bPKType = type.substring((EAAFConstants.URN_PREFIX_CDID).length()); - - else if (type.startsWith(EAAFConstants.URN_PREFIX_EIDAS)) - bPKType = type.substring((EAAFConstants.URN_PREFIX_EIDAS).length()); - - - if (bPKType != null ) { - log.trace("Authenticate user with bPK/wbPK " + bpk + " and Type=" + bPKType); - return bPKType + ":" + bpk; - - } else { - log.warn("Service Provider Target with: " + type + " is NOT supported. Set bPK as it is ..."); - return bpk; - - } - - } - - //TODO: update for complexe attributes - private Map converteIDASAttrToSimpleMap( - ImmutableMap, ImmutableSet>> attributeMap) { - Map result = new HashMap(); - - for (AttributeDefinition el : attributeMap.keySet()) { - - final Class parameterizedType = el.getParameterizedType(); - if ((DateTime.class).equals(parameterizedType)) { - DateTime attribute = eIDASResponseUtils.translateDateAttribute(el, attributeMap.get(el).asList()); - if (attribute != null) - result.put(el.getFriendlyName(), attribute); - else - log.info("Ignore empty 'DateTime' attribute"); - - } else if ((PostalAddress.class).equals(parameterizedType)) { - PostalAddress addressAttribute = eIDASResponseUtils.translateAddressAttribute(el, attributeMap.get(el).asList()); - if (addressAttribute != null) - result.put(el.getFriendlyName(), addressAttribute); - else - log.info("Ignore empty 'PostalAddress' attribute"); - - } else { - List natPersonIdObj = eIDASResponseUtils.translateStringListAttribute(el, attributeMap.get(el).asList()); - String stringAttr = natPersonIdObj.get(0); - if (StringUtils.isNotEmpty(stringAttr)) - result.put(el.getFriendlyName(), stringAttr); - else - log.info("Ignore empty 'String' attribute"); - - } - } - - return result; - } - - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java deleted file mode 100644 index 111aa00f..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/GenerateAuthnRequestTask.java +++ /dev/null @@ -1,306 +0,0 @@ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.tasks; - -import java.util.Map; -import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Component; -import org.springframework.web.util.UriComponentsBuilder; - -import com.google.common.collect.ImmutableSortedSet; - -import at.gv.egiz.eaaf.core.api.data.EAAFConstants; -import at.gv.egiz.eaaf.core.api.gui.IGUIFormBuilder; -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration; -import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; -import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage; -import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; -import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; -import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; -import at.gv.egiz.eidas.specific.connector.MSConnectorEventCodes; -import at.gv.egiz.eidas.specific.connector.MSeIDASNodeConstants; -import at.gv.egiz.eidas.specific.connector.gui.StaticGuiBuilderConfiguration; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.Constants; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASAuthenticationException; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.service.eIDASAttributeRegistry; -import eu.eidas.auth.commons.EidasParameterKeys; -import eu.eidas.auth.commons.attribute.AttributeDefinition; -import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; -import eu.eidas.auth.commons.light.ILightRequest; -import eu.eidas.auth.commons.light.impl.LightRequest; -import eu.eidas.auth.commons.protocol.eidas.SpType; -import eu.eidas.auth.commons.tx.BinaryLightToken; -import eu.eidas.specificcommunication.BinaryLightTokenHelper; -import eu.eidas.specificcommunication.SpecificCommunicationDefinitionBeanNames; -import eu.eidas.specificcommunication.exception.SpecificCommunicationException; -import eu.eidas.specificcommunication.protocol.impl.SpecificConnectorCommunicationServiceImpl; - -/** - * @author tlenz - * - */ -@Component("ConnecteIDASNodeTask") -public class GenerateAuthnRequestTask extends AbstractAuthServletTask { - private static final Logger log = LoggerFactory.getLogger(GenerateAuthnRequestTask.class); - - @Autowired IConfiguration basicConfig; - @Autowired eIDASAttributeRegistry attrRegistry; - @Autowired ApplicationContext context; - @Autowired ITransactionStorage transactionStore; - @Autowired IGUIFormBuilder guiBuilder; - - @Override - public void execute(ExecutionContext executionContext, - HttpServletRequest request, HttpServletResponse response) - throws TaskExecutionException { - - try{ - //get service-provider configuration - ISPConfiguration spConfig = pendingReq.getServiceProviderConfiguration(); - - // get target, environment and validate citizen countryCode - String citizenCountryCode = (String) executionContext.get(MSeIDASNodeConstants.REQ_PARAM_SELECTED_COUNTRY); - String environment = (String) executionContext.get(MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT); - - if (StringUtils.isEmpty(citizenCountryCode)) { - // illegal state; task should not have been executed without a selected country - throw new eIDASAuthenticationException("eidas.03", new Object[] { "" }); - - } - - //TODO: maybe add countryCode validation before request ref. impl. eIDAS node - log.debug("Request eIDAS auth. for citizen of country: " + citizenCountryCode); - revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.COUNTRY_SELECTED, citizenCountryCode); - - //build eIDAS AuthnRequest - LightRequest.Builder authnRequestBuilder = LightRequest.builder(); - authnRequestBuilder.id(UUID.randomUUID().toString()); - - - String issur = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_ENTITYID); - if (StringUtils.isEmpty(issur)) { - log.error("Found NO 'eIDAS node issuer' in configuration. Authentication NOT possible!"); - throw new EAAFConfigurationException("config.27", - new Object[] {"Application config containts NO " + Constants.CONIG_PROPS_EIDAS_NODE_ENTITYID }); - - } - authnRequestBuilder.issuer(issur); - - - //TODO: set matching mode if eIDAS ref. impl. support this method - - - //TODO: update if eIDAS ref. impl. supports exact matching for non-notified LoA schemes - String loa = EAAFConstants.EIDAS_LOA_HIGH; - if (spConfig.getRequiredLoA() != null) { - if (spConfig.getRequiredLoA().isEmpty()) - log.info("No eIDAS LoA requested. Use LoA HIGH as default"); - - else { - if (spConfig.getRequiredLoA().size() > 1 ) - log.info("Currently only ONE requested LoA is supported for service provider. Use first one ... "); - - loa = spConfig.getRequiredLoA().get(0); - - } - } - - log.debug("Request eIdAS node with LoA: " + loa); - authnRequestBuilder.levelOfAssurance(loa); - - //set correct SPType for requested target sector - String publicSectorTargetSelector = basicConfig.getBasicConfiguration( - Constants.CONIG_PROPS_EIDAS_NODE_PUBLICSECTOR_TARGETS, - Constants.POLICY_DEFAULT_ALLOWED_TARGETS); - Pattern p = Pattern.compile(publicSectorTargetSelector); - Matcher m = p.matcher(spConfig.getAreaSpecificTargetIdentifier()); - if (m.matches()) { - log.debug("Map " + spConfig.getAreaSpecificTargetIdentifier() + " to 'PublicSector'"); - authnRequestBuilder.spType(SpType.PUBLIC.getValue()); - - //TODO: only for eIDAS ref. node 2.0 and 2.1 because it need 'Providername' for any SPType - String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class); - if (StringUtils.isNotEmpty(providerName) - && basicConfig.getBasicMOAIDConfigurationBoolean( - Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME, - false) - ) - authnRequestBuilder.providerName(providerName); - - } else { - log.debug("Map " + spConfig.getAreaSpecificTargetIdentifier() + " to 'PrivateSector'"); - authnRequestBuilder.spType(SpType.PRIVATE.getValue()); - - //TODO: switch to RequesterId in further version - //set provider name for private sector applications - String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class); - if (StringUtils.isNotEmpty(providerName)) - authnRequestBuilder.providerName(providerName); - - } - - //set nameIDFormat - authnRequestBuilder.nameIdFormat(Constants.eIDAS_REQ_NAMEID_FORMAT); - - //set citizen country code for foreign uses - authnRequestBuilder.citizenCountryCode(citizenCountryCode); - - //set relay state - authnRequestBuilder.relayState(pendingReq.getPendingRequestId()); - - //build and add requested attribute set - ImmutableAttributeMap reqAttrMap = translateToEidasAttributes(attrRegistry.getAttributeSetFromConfiguration()); - authnRequestBuilder.requestedAttributes(reqAttrMap); - - //build request - LightRequest lightAuthnReq = authnRequestBuilder.build(); - - //put request into cache - BinaryLightToken token = putRequestInCommunicationCache(lightAuthnReq); - final String tokenBase64 = BinaryLightTokenHelper.encodeBinaryLightTokenBase64(token); - - //Workaround, because eIDAS node ref. impl. does not return relayState - if (basicConfig.getBasicMOAIDConfigurationBoolean( - Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_USEREQUESTIDASTRANSACTIONIDENTIFIER, - false)) { - log.trace("Put lightRequestId into transactionstore as session-handling backup"); - transactionStore.put(lightAuthnReq.getId(), pendingReq.getPendingRequestId(), -1); - - } - - //select forward URL regarding the selected environment - String forwardURL = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL); - if (StringUtils.isNotEmpty(environment)) - forwardURL = selectedForwardURLForEnvironment(environment); - - if (StringUtils.isEmpty(forwardURL)) { - log.warn("NO ForwardURL defined in configuration. Can NOT forward to eIDAS node! Process stops"); - throw new EAAFConfigurationException("config.08", new Object[] {Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL}); - - } - log.debug("ForwardURL: " + forwardURL + " selected to forward eIDAS request"); - - if (basicConfig.getBasicConfiguration( - Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_METHOD, - Constants.FORWARD_METHOD_GET - ).equals(Constants.FORWARD_METHOD_GET)) { - - log.debug("Use http-redirect for eIDAS node forwarding ... "); - //send redirect - UriComponentsBuilder redirectUrl = UriComponentsBuilder.fromHttpUrl(forwardURL); - redirectUrl.queryParam(EidasParameterKeys.TOKEN.toString(), tokenBase64); - response.sendRedirect(redirectUrl.build().encode().toString()); - - } else { - log.debug("Use http-post for eIDAS node forwarding ... "); - StaticGuiBuilderConfiguration config = new StaticGuiBuilderConfiguration( - basicConfig, - pendingReq, - Constants.TEMPLATE_POST_FORWARD_NAME, - null); - - config.putCustomParameter(Constants.TEMPLATE_POST_FORWARD_ENDPOINT, forwardURL); - config.putCustomParameter(Constants.TEMPLATE_POST_FORWARD_TOKEN_NAME, - EidasParameterKeys.TOKEN.toString()); - config.putCustomParameter(Constants.TEMPLATE_POST_FORWARD_TOKEN_VALUE, - tokenBase64); - - guiBuilder.build(response, config, "BKU-Selection form"); - - } - - revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.EIDAS_NODE_CONNECTED, lightAuthnReq.getId()); - - - } catch (eIDASAuthenticationException e) { - throw new TaskExecutionException(pendingReq, "eIDAS AuthnRequest generation FAILED.", e); - - } catch (Exception e) { - log.warn("eIDAS AuthnRequest generation FAILED.", e); - throw new TaskExecutionException(pendingReq, e.getMessage(), e); - - } - - } - - /** - * Select a forward URL from configuration for a specific environment - *

- * Info: This method is needed, because eIDAS Ref. Impl only supports one countrycode on each instance. - * In consequence, more than one eIDAS Ref. Impl nodes are required to support producation, testing, or QS stages - * for one country by using one ms-specific eIDAS connector - * - * @param environment Environment selector from CountrySlection page - * @return - */ - private String selectedForwardURLForEnvironment(String environment) { - log.trace("Starting endpoint selection process for environment: " + environment + " ... "); - if (environment.equalsIgnoreCase(MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_PRODUCTION)) - return basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL); - - else if (environment.equalsIgnoreCase(MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_QS)) - return basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL - + "." + MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_QS); - - else if (environment.equalsIgnoreCase(MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_TESTING)) - return basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL - + "." + MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_TESTING); - - else if (environment.equalsIgnoreCase(MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_DEVELOPMENT)) - return basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_FORWARD_URL - + "." + MSeIDASNodeConstants.REQ_PARAM_SELECTED_ENVIRONMENT_VALUE_DEVELOPMENT); - - log.info("Environment selector: " + environment + " is not supported"); - return null; - - } - - private ImmutableAttributeMap translateToEidasAttributes(final Map requiredAttributes) { - ImmutableAttributeMap.Builder builder = ImmutableAttributeMap.builder(); - for (Map.Entry attribute : requiredAttributes.entrySet()) { - final String name = attribute.getKey(); - final ImmutableSortedSet> byFriendlyName = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(name); - if (!byFriendlyName.isEmpty()) { - final AttributeDefinition attributeDefinition = byFriendlyName.first(); - builder.put(AttributeDefinition.builder(attributeDefinition).required(attribute.getValue()).build()); - - } else - log.warn("Can NOT request UNKNOWN attribute: " + attribute.getKey() + " Ignore it!"); - - } - - return builder.build(); - - } - - private BinaryLightToken putRequestInCommunicationCache(ILightRequest iLightRequest) throws ServletException { - final BinaryLightToken binaryLightToken; - try { - final SpecificConnectorCommunicationServiceImpl springManagedSpecificConnectorCommunicationService = - (SpecificConnectorCommunicationServiceImpl) context.getBean(SpecificCommunicationDefinitionBeanNames.SPECIFIC_CONNECTOR_COMMUNICATION_SERVICE.toString()); - - binaryLightToken = springManagedSpecificConnectorCommunicationService.putRequest(iLightRequest); - - } catch (SpecificCommunicationException e) { - log.error("Unable to process specific request"); - throw new ServletException(e); - - } - - return binaryLightToken; - } - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/ReceiveAuthnResponseTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/ReceiveAuthnResponseTask.java deleted file mode 100644 index 16030c52..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/tasks/ReceiveAuthnResponseTask.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - *******************************************************************************/ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.tasks; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Component; - -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; -import at.gv.egiz.eaaf.core.exceptions.EAAFException; -import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; -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.eidas.specific.connector.MSConnectorEventCodes; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.Constants; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASAuthenticationException; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.service.eIDASAttributeRegistry; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.validator.eIDASResponseValidator; -import eu.eidas.auth.commons.light.ILightResponse; - -@Component("ReceiveResponseFromeIDASNodeTask") -public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { - private static final Logger log = LoggerFactory.getLogger(ReceiveAuthnResponseTask.class); - - @Autowired private ApplicationContext context; - @Autowired private IConfiguration basicConfig; - @Autowired private eIDASAttributeRegistry attrRegistry; - - @Override - public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) throws TaskExecutionException { - try{ - ILightResponse eIDASResponse = (ILightResponse) request.getAttribute(Constants.DATA_FULL_EIDAS_RESPONSE); - if (eIDASResponse == null) { - log.warn("NO eIDAS response-message found."); - throw new eIDASAuthenticationException("eidas.01", null); - - } - - log.debug("Receive eIDAS response with RespId:" + eIDASResponse.getId() + " for ReqId:" + eIDASResponse.getInResponseToId()); - revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.RESPONSE_FROM_EIDAS_NODE, eIDASResponse.getId()); - - - //check response StatusCode - if (!eIDASResponse.getStatus().getStatusCode().equals(Constants.SUCCESS_URI)) { - log.info("Receice eIDAS Response with StatusCode:" + eIDASResponse.getStatus().getStatusCode() - + " Subcode:" + eIDASResponse.getStatus().getSubStatusCode() + " Msg:" + eIDASResponse.getStatus().getStatusMessage()); - throw new eIDASAuthenticationException("eidas.02", new Object[]{eIDASResponse.getStatus().getStatusCode(), eIDASResponse.getStatus().getStatusMessage()}); - - } - - // extract all Attributes from response - - - - // ********************************************************** - // ******* MS-specificresponse validation ********** - // ********************************************************** - String spCountry = basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, "AT"); - eIDASResponseValidator.validateResponse(pendingReq, eIDASResponse, spCountry, attrRegistry); - - - // ********************************************************** - // ******* Store resonse infos into session object ********** - // ********************************************************** - - //update MOA-Session data with received information - log.debug("Store eIDAS response information into pending-request."); - AuthProcessDataWrapper authProcessData = pendingReq.getSessionData(AuthProcessDataWrapper.class); - authProcessData.setQAALevel(eIDASResponse.getLevelOfAssurance()); - authProcessData.setGenericDataToSession(Constants.DATA_FULL_EIDAS_RESPONSE, eIDASResponse); - - //store MOA-session to database - requestStoreage.storePendingRequest(pendingReq); - - revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.RESPONSE_FROM_EIDAS_NODE_VALID); - - } catch (EAAFException e) { - revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.RESPONSE_FROM_EIDAS_NODE_NOT_VALID); - throw new TaskExecutionException(pendingReq, "eIDAS Response processing FAILED.", e); - - } catch (Exception e) { - log.warn("eIDAS Response processing FAILED.", e); - revisionsLogger.logEvent(pendingReq, MSConnectorEventCodes.RESPONSE_FROM_EIDAS_NODE_NOT_VALID); - throw new TaskExecutionException(pendingReq, e.getMessage(), - new eIDASAuthenticationException("eidas.05", new Object[]{e.getMessage()}, e)); - - } - - } - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/utils/LoggingHandler.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/utils/LoggingHandler.java deleted file mode 100644 index c58d369b..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/utils/LoggingHandler.java +++ /dev/null @@ -1,52 +0,0 @@ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.utils; - -import java.io.ByteArrayOutputStream; -import java.util.Set; - -import javax.xml.namespace.QName; -import javax.xml.soap.SOAPMessage; -import javax.xml.ws.handler.MessageContext; -import javax.xml.ws.handler.soap.SOAPHandler; -import javax.xml.ws.handler.soap.SOAPMessageContext; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class LoggingHandler implements SOAPHandler { - - Logger log = LoggerFactory.getLogger(LoggingHandler.class); - - public boolean handleMessage(SOAPMessageContext context) { - SOAPMessage msg = context.getMessage(); - boolean request = ((Boolean) context - .get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue(); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - - try { - if (request) { - msg.writeTo(bos); - } else { // This is the response message - msg.writeTo(bos); - } - - log.trace(bos.toString()); - log.trace(new String(bos.toByteArray())); - - } catch (Exception e) { - log.trace(e.getMessage(), e); - } - return true; - } - - public boolean handleFault(SOAPMessageContext context) { - return handleMessage(context); - } - - public void close(MessageContext context) { - } - - public Set getHeaders() { - return null; - } - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/utils/eIDASResponseUtils.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/utils/eIDASResponseUtils.java deleted file mode 100644 index 165c35cb..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/utils/eIDASResponseUtils.java +++ /dev/null @@ -1,98 +0,0 @@ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.utils; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.joda.time.DateTime; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.ImmutableList; - -import at.gv.egiz.eaaf.core.impl.data.Trible; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.Constants; -import eu.eidas.auth.commons.attribute.AttributeDefinition; -import eu.eidas.auth.commons.attribute.AttributeValue; -import eu.eidas.auth.commons.attribute.AttributeValueMarshaller; -import eu.eidas.auth.commons.attribute.AttributeValueMarshallingException; -import eu.eidas.auth.commons.protocol.eidas.impl.PostalAddress; - -public class eIDASResponseUtils { - private static final Logger log = LoggerFactory.getLogger(eIDASResponseUtils.class); - - public static final String PERSONALIDENIFIER_VALIDATION_PATTERN = "^[A-Z,a-z]{2}/[A-Z,a-z]{2}/.*"; - - /** - * Validate a eIDAS PersonalIdentifier attribute value - * This validation is done according to eIDAS SAML Attribute Profile - Section 2.2.3 Unique Identifier - * - * @param uniqueID eIDAS attribute value of a unique identifier - * @return true if the uniqueID matches to eIDAS to Unique Identifier specification, otherwise false - */ - public static boolean validateEidasPersonalIdentifier(String uniqueID) { - Pattern pattern = Pattern.compile(PERSONALIDENIFIER_VALIDATION_PATTERN ); - Matcher matcher = pattern.matcher(uniqueID); - return matcher.matches(); - - } - - - /** - * Parse an eIDAS PersonalIdentifier attribute value into it components. - * This processing is done according to eIDAS SAML Attribute Profile - Section 2.2.3 Unique Identifier - * - * @param uniqueID eIDAS attribute value of a unique identifier - * @return {@link Trible} that contains: - *
First : citizen country - *
Second: destination country - *
Third : unique identifier - *
or null if the attribute value has a wrong format - */ - public static Trible parseEidasPersonalIdentifier(String uniqueID) { - if (!validateEidasPersonalIdentifier(uniqueID)) { - log.error("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER - + " looks wrong formated. Value:" + ((String)uniqueID)); - return null; - - } - return Trible.newInstance(uniqueID.substring(0, 2), uniqueID.substring(3, 5), uniqueID.substring(6)); - - } - - public static List translateStringListAttribute(AttributeDefinition attributeDefinition, ImmutableList> attributeValues) { - final List stringListAttribute = new ArrayList(); - AttributeValueMarshaller attributeValueMarshaller = attributeDefinition.getAttributeValueMarshaller(); - for (AttributeValue attributeValue : attributeValues) { - String valueString = null; - try { - valueString = attributeValueMarshaller.marshal((AttributeValue) attributeValue); - stringListAttribute.add(valueString); - } catch (AttributeValueMarshallingException e) { - throw new IllegalStateException(e); - - } - } - - return stringListAttribute; - - } - - public static DateTime translateDateAttribute(AttributeDefinition attributeDefinition, ImmutableList> attributeValues) { - if (attributeValues.size() != 0) { - final AttributeValue firstAttributeValue = attributeValues.get(0); - return (DateTime) firstAttributeValue.getValue(); - - } - - return null; - } - - public static PostalAddress translateAddressAttribute(AttributeDefinition attributeDefinition, ImmutableList> attributeValues) { - final AttributeValue firstAttributeValue = attributeValues.get(0); - return (PostalAddress) firstAttributeValue.getValue(); - - } - -} diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java deleted file mode 100644 index 3791d0d7..00000000 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/gv/egiz/eidas/specific/modules/authmodule_eIDASv2/validator/eIDASResponseValidator.java +++ /dev/null @@ -1,135 +0,0 @@ -package at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.validator; - -import java.util.List; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.ImmutableList; - -import at.gv.egiz.eaaf.core.api.IRequest; -import at.gv.egiz.eaaf.core.impl.data.Trible; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.Constants; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.exception.eIDASValidationException; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.service.eIDASAttributeRegistry; -import at.gv.egiz.eidas.specific.modules.authmodule_eIDASv2.utils.eIDASResponseUtils; -import eu.eidas.auth.commons.attribute.AttributeDefinition; -import eu.eidas.auth.commons.attribute.AttributeValue; -import eu.eidas.auth.commons.light.ILightResponse; -import eu.eidas.auth.commons.protocol.eidas.LevelOfAssurance; - -/** - * @author tlenz - * - */ -public class eIDASResponseValidator { - private static final Logger log = LoggerFactory.getLogger(eIDASResponseValidator.class); - - public static void validateResponse(IRequest pendingReq, ILightResponse eIDASResponse, String spCountry, eIDASAttributeRegistry attrRegistry) throws eIDASValidationException { - - /*-----------------------------------------------------| - * validate received LoA against minimum required LoA | - *_____________________________________________________| - */ - LevelOfAssurance respLoA = LevelOfAssurance.fromString(eIDASResponse.getLevelOfAssurance()); - List allowedLoAs = pendingReq.getServiceProviderConfiguration().getRequiredLoA(); - boolean loaValid = false; - for (String allowedLoaString : allowedLoAs) { - LevelOfAssurance allowedLoa = LevelOfAssurance.fromString(allowedLoaString); - if (respLoA.numericValue() >= allowedLoa.numericValue()) { - log.debug("Response contains valid LoA. Resume process ... "); - loaValid = true; - break; - - } else - log.trace("Allowed LoA: " + allowedLoaString + " DOES NOT match response LoA: " + eIDASResponse.getLevelOfAssurance()); - - } - - if (!loaValid) { - log.error("eIDAS Response LevelOfAssurance is lower than the required! " - + "(Resp-LoA:" + respLoA.getValue() + " Req-LoA:" + allowedLoAs.toArray() + ")"); - throw new eIDASValidationException("eidas.06", new Object[]{respLoA.getValue()}); - - } - - - - /*-----------------------------------------------------| - * validate 'PersonalIdentifier' attribute | - *_____________________________________________________| - */ - AttributeDefinition attrDefinition = attrRegistry.getCoreAttributeRegistry().getByFriendlyName(Constants.eIDAS_ATTR_PERSONALIDENTIFIER).first(); - final ImmutableList> attributeValues = eIDASResponse.getAttributes().getAttributeMap().get(attrDefinition).asList(); - List personalIdObj = eIDASResponseUtils.translateStringListAttribute(attrDefinition, attributeValues); - - //check if attribute exists - if (personalIdObj == null || personalIdObj.isEmpty()) { - log.warn("eIDAS Response include NO 'PersonalIdentifier' attriubte " - + ".... That can be a BIG problem in further processing steps"); - throw new eIDASValidationException("eidas.05", new Object[] {"NO 'PersonalIdentifier' attriubte"}); - - } else if (personalIdObj.size() > 1) { - log.warn("eIDAS Response include MORE THAN ONE 'PersonalIdentifier' attriubtes " - + ".... That can be a BIG problem in further processing steps"); - throw new eIDASValidationException("eidas.05", new Object[] {"MORE THAN ONE 'PersonalIdentifier' attriubtes"}); - - } else { - String natPersId = personalIdObj.get(0); - //validate attribute value format - Trible split = - eIDASResponseUtils.parseEidasPersonalIdentifier(natPersId); - if (split == null) { - throw new eIDASValidationException("eidas.07", - new Object[]{ - Constants.eIDAS_ATTR_PERSONALIDENTIFIER, - "Wrong identifier format"}); - - } else { - //validation according to eIDAS SAML Attribute Profile, Section 2.2.3 - if (StringUtils.isEmpty(split.getSecond())) { - log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER - + " includes NO destination country. Value:" + natPersId); - throw new eIDASValidationException("eidas.07", - new Object[]{ - Constants.eIDAS_ATTR_PERSONALIDENTIFIER, - "No or empty destination country"}); - - } - if (!split.getSecond().equalsIgnoreCase(spCountry)) { - log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER - + " includes wrong destination country. Value:" + natPersId - + " SP-Country:" + spCountry); - throw new eIDASValidationException("eidas.07", - new Object[]{ - Constants.eIDAS_ATTR_PERSONALIDENTIFIER, - "Destination country does not match to SP country"}); - - } - - if (StringUtils.isEmpty(split.getFirst())) { - log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER - + " includes NO citizen country. Value:" + natPersId); - throw new eIDASValidationException("eidas.07", - new Object[]{ - Constants.eIDAS_ATTR_PERSONALIDENTIFIER, - "No or empty citizen country"}); - - } - if (!split.getSecond().equalsIgnoreCase(spCountry)) { - log.warn("eIDAS attribute value for " + Constants.eIDAS_ATTR_PERSONALIDENTIFIER - + " includes a relaying-party country that does not match to service-provider country. " - + " Value:" + natPersId - + " SP Country:" + spCountry); - throw new eIDASValidationException("eidas.07", - new Object[]{ - Constants.eIDAS_ATTR_PERSONALIDENTIFIER, - "Citizen country does not match to eIDAS-node country that generates the response"}); - - } - } - } - - } -} -- cgit v1.2.3