From 8942276a3e03923cfc1d162582ca0f734a54ea90 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Mon, 16 May 2022 11:30:58 +0200 Subject: fix(matching): optimize prozess handling during alternative eIDAS authentication --- modules/authmodule-eIDAS-v2/pom.xml | 10 +- .../auth/eidas/v2/tasks/AlternativeSearchTask.java | 37 +- .../messages/eidas_connector_message.properties | 7 +- .../AlternativeSearchTaskWithRegisterTest.java | 52 +-- .../EidasAttributePostProcessingTest.java | 403 +++++++++------------ 5 files changed, 216 insertions(+), 293 deletions(-) (limited to 'modules/authmodule-eIDAS-v2') diff --git a/modules/authmodule-eIDAS-v2/pom.xml b/modules/authmodule-eIDAS-v2/pom.xml index 2cb8d82e..1d18aac0 100644 --- a/modules/authmodule-eIDAS-v2/pom.xml +++ b/modules/authmodule-eIDAS-v2/pom.xml @@ -368,13 +368,17 @@ false - **/at/gv/e_government/reference/namespace/persondata/_20020228/* - **/org/w3/_2000/_09/* - **/org/w3/_2001/_04/* **/szrservices/* **/generated/cxf/* **at/gv/bmi/namespace/* **at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/ernp/* + org/w3/_2000/**/* + at/gv/bmi/namespace/**/* + at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/ernp/**/* + at/gv/bmi/namespace/**/* + at/gv/e_government/reference/namespace/**/* + org/w3/_2000/_09/**/* + org/xmlsoap/schemas/ws/**/* diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java index 96aa9c51..e8fb5b6b 100644 --- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java +++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java @@ -81,6 +81,7 @@ import lombok.extern.slf4j.Slf4j; public class AlternativeSearchTask extends AbstractAuthServletTask { private static final String MSG_PROP_25 = "module.eidasauth.matching.25"; + private static final String MSG_PROP_26 = "module.eidasauth.matching.26"; private final RegisterSearchService registerSearchService; private final ICcSpecificEidProcessingService eidPostProcessor; @@ -107,11 +108,17 @@ public class AlternativeSearchTask extends AbstractAuthServletTask { MatchingTaskUtils.getIntermediateMatchingResult(pendingReq); //pre-validation of eIDAS data - preVerifyAlternativeEidasData(altEidasData, initialEidasData, intermediateMatchingState); - - //perform register search operation based on alterantive eIDAS data - step11RegisterSearchWithPersonIdentifier(executionContext, altEidasData, - intermediateMatchingState, initialEidasData); + if (!preVerifyAlternativeEidasData(altEidasData, initialEidasData, + intermediateMatchingState, executionContext)) { + executionContext.put(TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK, true); + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED, true); + + } else { + //perform register search operation based on alterantive eIDAS data + step11RegisterSearchWithPersonIdentifier(executionContext, altEidasData, + intermediateMatchingState, initialEidasData); + + } } catch (WorkflowException e) { throw new TaskExecutionException(pendingReq, "Initial search failed", e); @@ -131,10 +138,12 @@ public class AlternativeSearchTask extends AbstractAuthServletTask { * @param altEidasData eIDAS data from alternative authentication * @param initialEidasData eIDAS data from initial authentication * @param intermediateMatchingState Intermediate matching result + * @param executionContext Current execution context state + * @return true if the current state is valid, otherwise false * @throws WorkflowException In case of a validation error */ - private void preVerifyAlternativeEidasData(SimpleEidasData altEidasData, SimpleEidasData initialEidasData, - RegisterStatusResults intermediateMatchingState) throws WorkflowException { + private boolean preVerifyAlternativeEidasData(SimpleEidasData altEidasData, SimpleEidasData initialEidasData, + RegisterStatusResults intermediateMatchingState, ExecutionContext executionContext) throws WorkflowException { if (initialEidasData == null) { throw new WorkflowException("step11", "No initial eIDAS authn data", true); @@ -146,14 +155,22 @@ public class AlternativeSearchTask extends AbstractAuthServletTask { } if (!Objects.equals(altEidasData.getCitizenCountryCode(), initialEidasData.getCitizenCountryCode())) { - throw new WorkflowException("step11", "Country Code of alternative eIDAS authn not matching", true); + log.warn("CountryCode: {} from alternative eIDAS authentication DOES NOT match to initial countryCode: {}", + altEidasData.getCitizenCountryCode(), initialEidasData.getCitizenCountryCode()); + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON, MSG_PROP_26); + return false; + } if (!altEidasData.equalsMds(initialEidasData)) { - throw new WorkflowException("step11", "MDS of alternative eIDAS authn does not match initial authn", true); + log.warn("MDS from alternative eIDAS authentication DOES NOT match to initial MDS"); + executionContext.put(CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON, MSG_PROP_26); + return false; } + + return true; } private void step11RegisterSearchWithPersonIdentifier( @@ -229,7 +246,7 @@ public class AlternativeSearchTask extends AbstractAuthServletTask { MatchingTaskUtils.storeFinalMatchingResult(pendingReq, result); //remove intermediate matching-state - MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, null); + //MatchingTaskUtils.storeIntermediateMatchingResult(pendingReq, null); } diff --git a/modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties b/modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties index bd05fef2..6d73c43a 100644 --- a/modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties +++ b/modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties @@ -23,11 +23,12 @@ module.eidasauth.matching.04=An error occurred while loading your data from offi module.eidasauth.matching.11=Matching failed, because of an ERnP communication error. Reason: {0} module.eidasauth.matching.12=Matching failed, because ERnP response contains historic information which is not supported. -module.eidasauth.matching.21=Matching be using residence information failed by missing input information. Use another method for matching or create a new Austrian identity. -module.eidasauth.matching.22=Can not find an unique match by using residence information. Provide more or other data, use another method for matching, or create a new Austrian identity. +module.eidasauth.matching.21=Matching be using residence information failed by missing input information. Use another method for matching. +module.eidasauth.matching.22=Can not find an unique match by using residence information. Provide more or other data or use another method for matching. module.eidasauth.matching.23=Matching be using Austrian Identity was canceled. Use another method for matching or create a new Austrian identity. module.eidasauth.matching.24=Matching be using Austrian Identity not possible. Use another method for matching or create a new Austrian identity. -module.eidasauth.matching.25=Matching be using alternative eIDAS authentication not possible. Provide more or other data, use another method for matching, or create a new Austrian identity. +module.eidasauth.matching.25=Matching be using alternative eIDAS authentication not possible. Provide more or other data or use another method for matching. +module.eidasauth.matching.26=Matching be using alternative eIDAS authentication not possible, because Name or Country not matched. Provide more or other data or use another method for matching. module.eidasauth.matching.99=Matching failed, because of an unexpected processing error. Reason: {0} diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java index 3814c632..682db41e 100644 --- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java +++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/AlternativeSearchTaskWithRegisterTest.java @@ -27,7 +27,6 @@ import javax.xml.namespace.QName; import org.apache.commons.lang3.RandomStringUtils; import org.jetbrains.annotations.NotNull; -import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; @@ -252,19 +251,17 @@ public class AlternativeSearchTaskWithRegisterTest { Constants.DATA_FULL_EIDAS_RESPONSE_ALTERNATIVE, buildDummyAuthResponse("XXXKlaus - Maria", "XXXvon Brandenburg", "EE/AT/7cEYasdfsafsaf4CDVzNT4E7cjkU4VqForjUnit", "1994-12-31")); - - + // execute task - TaskExecutionException exception = assertThrows(TaskExecutionException.class, - () -> task.execute(pendingReq, executionContext)); + task.execute(pendingReq, executionContext); // validate state - assertTrue("Wrong exception", (exception.getOriginalException() instanceof WorkflowException)); - assertEquals("wrong errorparam 1", "step11", ((EaafException) exception.getOriginalException()).getParams()[0]); - assertTrue("Wrong flag 'step11'", - ((WorkflowException) exception.getOriginalException()).isRequiresManualFix()); - assertEquals("wrong errorparam 1", "Country Code of alternative eIDAS authn not matching", - ((EaafException) exception.getOriginalException()).getParams()[1]); + assertNotNull("find no eIDAS inbut data", MatchingTaskUtils.getInitialEidasData(pendingReq)); + assertNull("final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); + assertEquals("wrong executionContextFlag 'alternative eIDAS result'", true, + executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.26", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); } @@ -301,16 +298,15 @@ public class AlternativeSearchTaskWithRegisterTest { // execute task - TaskExecutionException exception = assertThrows(TaskExecutionException.class, - () -> task.execute(pendingReq, executionContext)); + task.execute(pendingReq, executionContext); // validate state - assertTrue("Wrong exception", (exception.getOriginalException() instanceof WorkflowException)); - assertEquals("wrong errorparam 1", "step11", ((EaafException) exception.getOriginalException()).getParams()[0]); - assertTrue("Wrong flag 'step11'", - ((WorkflowException) exception.getOriginalException()).isRequiresManualFix()); - assertEquals("wrong errorparam 1", "MDS of alternative eIDAS authn does not match initial authn", - ((EaafException) exception.getOriginalException()).getParams()[1]); + assertNotNull("find no eIDAS inbut data", MatchingTaskUtils.getInitialEidasData(pendingReq)); + assertNull("final matching result", MatchingTaskUtils.getFinalMatchingResult(pendingReq)); + assertEquals("wrong executionContextFlag 'alternative eIDAS result'", true, + executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK)); + assertEquals("matching failed flag", true, executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED)); + assertEquals("failed reason", "module.eidasauth.matching.26", executionContext.get(Constants.CONTEXT_FLAG_ADVANCED_MATCHING_FAILED_REASON)); } @@ -887,8 +883,6 @@ public class AlternativeSearchTaskWithRegisterTest { private void checkMatchingSuccessState(IRequest pendingReq, String bpk, String familyName, String givenName, String birhday, String countryCode) { - assertNull("Find intermediate matching data but matching should be finished", - MatchingTaskUtils.getIntermediateMatchingResult(pendingReq)); assertNotNull("find no eIDAS inbut data", MatchingTaskUtils.getInitialEidasData(pendingReq)); MatchedPersonResult personInfo = MatchingTaskUtils.getFinalMatchingResult(pendingReq); @@ -901,22 +895,6 @@ public class AlternativeSearchTaskWithRegisterTest { } - private void checkIntermediateResult(int resultSize) { - Boolean transitionGUI = (Boolean) executionContext.get(Constants.TRANSITION_TO_GENERATE_OTHER_LOGIN_METHOD_GUI_TASK); - Assert.assertTrue("Wrong transition", transitionGUI); - Boolean transitionErnb = (Boolean) executionContext.get(Constants.TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK); - Assert.assertNull("Wrong transition", transitionErnb); - - assertNotNull("find no eIDAS inbut data", MatchingTaskUtils.getInitialEidasData(pendingReq)); - assertNull("Find final matching data but no match sould be found", - MatchingTaskUtils.getFinalMatchingResult(pendingReq)); - - RegisterStatusResults result = MatchingTaskUtils.getIntermediateMatchingResult(pendingReq); - assertNotNull("Find no intermediate matching data", result); - assertEquals("wrong intermediate result size", resultSize, result.getResultCount()); - - } - @NotNull private AuthenticationResponse buildDummyAuthResponse(String givenName, String familyName, String identifier, String dateOfBirth) throws URISyntaxException { diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java index 0a4ab851..867eac4a 100644 --- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java +++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java @@ -23,14 +23,14 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.validation; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import java.io.IOException; -import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Map; -import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; +import org.apache.commons.lang3.RandomStringUtils; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @@ -41,12 +41,15 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.CcSpecificEidProcessingService; +import lombok.SneakyThrows; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "/SpringTest-context_tasks_test.xml", - "/SpringTest-context_basic_mapConfig.xml"}) + "/SpringTest-context_basic_mapConfig.xml" }) @DirtiesContext(classMode = ClassMode.AFTER_CLASS) public class EidasAttributePostProcessingTest { @@ -113,6 +116,16 @@ public class EidasAttributePostProcessingTest { private static final String P2_PLACEOFBIRTH = "Nirgendwo"; private static final String P2_BIRTHNAME = "Musterkind"; + + private static final String P8_eIDASID_PID = RandomStringUtils.randomAlphabetic(10); + private static final String P8_eIDASID ="EL/AT/" + P8_eIDASID_PID; + private static final String P8_GIVENNAME = RandomStringUtils.randomAlphabetic(10); + private static final String P8_FAMILYNAME = RandomStringUtils.randomAlphabetic(10); + private static final String P8_DATEOFBIRTH = "2028-05-11"; + private static final String P8_PLACEOFBIRTH = RandomStringUtils.randomAlphabetic(10); + private static final String P8_BIRTHNAME = RandomStringUtils.randomAlphabetic(10); + + /** * jUnit class initializer. * @@ -126,149 +139,140 @@ public class EidasAttributePostProcessingTest { } @Test - public void deWithHexLowerCase() throws Exception { - try { - final SimpleEidasData result = postProcessor.postProcess( - generateInputData( - P1_eIDASID, - P1_FAMILYNAME, - P1_GIVENNAME, - P1_DATEOFBIRTH, - P1_PLACEOFBIRTH, - P1_BIRTHNAME)); + @SneakyThrows + public void deWithHexLowerCase() { + final SimpleEidasData result = postProcessor.postProcess( + generateInputData( + P1_eIDASID, + P1_FAMILYNAME, + P1_GIVENNAME, + P1_DATEOFBIRTH, + P1_PLACEOFBIRTH, + P1_BIRTHNAME)); + + validate(result, + "Uy6qvZV0iA2/drm4zACDLCCm7BE9aCKZVQ16bg80XiU=", + "DE", + P1_FAMILYNAME, + P1_GIVENNAME, + P1_DATEOFBIRTH, + P1_PLACEOFBIRTH, + P1_BIRTHNAME); - validate(result, - "Uy6qvZV0iA2/drm4zACDLCCm7BE9aCKZVQ16bg80XiU=", - P1_FAMILYNAME, - P1_GIVENNAME, - P1_DATEOFBIRTH, - P1_PLACEOFBIRTH, - P1_BIRTHNAME); - - } catch (final Exception e) { - e.printStackTrace(); - fail(e.getMessage()); - - } } @Test - public void deWithHexMixedCase() throws Exception { - try { - final SimpleEidasData result = postProcessor.postProcess( - generateInputData( - P3_eIDASID, - P3_FAMILYNAME, - P3_GIVENNAME, - P3_DATEOFBIRTH, - P3_PLACEOFBIRTH, - P3_BIRTHNAME)); - - validate(result, - "Uy6qvZV0iA2/drm4zACDLCCm7BE9aCKZVQ16bg80XiU=", - P3_FAMILYNAME, - P3_GIVENNAME, - P3_DATEOFBIRTH, - P3_PLACEOFBIRTH, - P3_BIRTHNAME); - - } catch (final Exception e) { - e.printStackTrace(); - fail(e.getMessage()); - - } + @SneakyThrows + public void deWithHexMixedCase() { + final SimpleEidasData result = postProcessor.postProcess( + generateInputData( + P3_eIDASID, + P3_FAMILYNAME, + P3_GIVENNAME, + P3_DATEOFBIRTH, + P3_PLACEOFBIRTH, + P3_BIRTHNAME)); + + validate(result, + "Uy6qvZV0iA2/drm4zACDLCCm7BE9aCKZVQ16bg80XiU=", + "DE", + P3_FAMILYNAME, + P3_GIVENNAME, + P3_DATEOFBIRTH, + P3_PLACEOFBIRTH, + P3_BIRTHNAME); } @Test - public void deWithHexUpperCase() throws Exception { - try { - final SimpleEidasData result = postProcessor.postProcess( - generateInputData( - P4_eIDASID, - P4_FAMILYNAME, - P4_GIVENNAME, - P4_DATEOFBIRTH, - P4_PLACEOFBIRTH, - P4_BIRTHNAME)); + @SneakyThrows + public void deWithHexUpperCase() { + final SimpleEidasData result = postProcessor.postProcess( + generateInputData( + P4_eIDASID, + P4_FAMILYNAME, + P4_GIVENNAME, + P4_DATEOFBIRTH, + P4_PLACEOFBIRTH, + P4_BIRTHNAME)); + + validate(result, + "Uy6qvZV0iA2/drm4zACDLCCm7BE9aCKZVQ16bg80XiU=", + "DE", + P4_FAMILYNAME, + P4_GIVENNAME, + P4_DATEOFBIRTH, + P4_PLACEOFBIRTH, + P4_BIRTHNAME); - validate(result, - "Uy6qvZV0iA2/drm4zACDLCCm7BE9aCKZVQ16bg80XiU=", - P4_FAMILYNAME, - P4_GIVENNAME, - P4_DATEOFBIRTH, - P4_PLACEOFBIRTH, - P4_BIRTHNAME); - - } catch (final Exception e) { - e.printStackTrace(); - fail(e.getMessage()); - - } } @Test public void deWithHexTooLongCase() throws Exception { - try { - postProcessor.postProcess( - generateInputData( - P5_eIDASID, - P5_FAMILYNAME, - P5_GIVENNAME, - P5_DATEOFBIRTH, - P5_PLACEOFBIRTH, - P5_BIRTHNAME)); + assertThrows("missing exception", EidasSAuthenticationException.class, + () -> postProcessor.postProcess( + generateInputData( + P5_eIDASID, + P5_FAMILYNAME, + P5_GIVENNAME, + P5_DATEOFBIRTH, + P5_PLACEOFBIRTH, + P5_BIRTHNAME))); - } catch (final Exception e) { - return; - - } - - fail("Too long input accepted"); } @Test public void deWithHexTooShortCase() throws Exception { - try { - postProcessor.postProcess( - generateInputData( - P6_eIDASID, - P6_FAMILYNAME, - P6_GIVENNAME, - P6_DATEOFBIRTH, - P6_PLACEOFBIRTH, - P6_BIRTHNAME)); + assertThrows("missing exception", EidasSAuthenticationException.class, + () -> postProcessor.postProcess( + generateInputData( + P6_eIDASID, + P6_FAMILYNAME, + P6_GIVENNAME, + P6_DATEOFBIRTH, + P6_PLACEOFBIRTH, + P6_BIRTHNAME))); - } catch (final Exception e) { - return; + } - } + @Test + public void deWithNoHexCase() throws Exception { + assertThrows("missing exception", EidasSAuthenticationException.class, + () -> postProcessor.postProcess( + generateInputData( + P7_eIDASID, + P7_FAMILYNAME, + P7_GIVENNAME, + P7_DATEOFBIRTH, + P7_PLACEOFBIRTH, + P7_BIRTHNAME))); - fail("Too short input accepted"); } @Test - public void deWithNoHexCase() throws Exception { - try { - postProcessor.postProcess( + public void elTestCase() throws Exception { + final SimpleEidasData result = postProcessor.postProcess( generateInputData( - P7_eIDASID, - P7_FAMILYNAME, - P7_GIVENNAME, - P7_DATEOFBIRTH, - P7_PLACEOFBIRTH, - P7_BIRTHNAME)); - - } catch (final Exception e) { - return; + P8_eIDASID, + P8_FAMILYNAME, + P8_GIVENNAME, + P8_DATEOFBIRTH, + P8_PLACEOFBIRTH, + P8_BIRTHNAME)); - } + validate(result, + P8_eIDASID_PID, + "GR", + P8_FAMILYNAME, + P8_GIVENNAME, + P8_DATEOFBIRTH, + P8_PLACEOFBIRTH, + P8_BIRTHNAME); - fail("Not hex encoded input accepted"); } - + + @Test public void eeTestCase() throws Exception { - try { final SimpleEidasData result = postProcessor.postProcess( generateInputData( P2_eIDASID, @@ -280,137 +284,73 @@ public class EidasAttributePostProcessingTest { validate(result, "asfasfasdfasdfasdfasdfasdfasvafasdfasdfasdfasdfasdfasvascasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasd", + "EE", P2_FAMILYNAME, P2_GIVENNAME, P2_DATEOFBIRTH, P2_PLACEOFBIRTH, P2_BIRTHNAME); - } catch (final Exception e) { - e.printStackTrace(); - fail(e.getMessage()); - - } } @Test public void eeTestFamilyNameMissingCase() throws Exception { - try { - final SimpleEidasData result = postProcessor.postProcess( + assertThrows("missing exception", EidasSAuthenticationException.class, + () -> postProcessor.postProcess( generateInputData( P2_eIDASID, null, P2_GIVENNAME, P2_DATEOFBIRTH, P2_PLACEOFBIRTH, - P2_BIRTHNAME)); - - validate(result, - "asfasfasdfasdfasdfasdfasdfasvafasdfasdfasdfasdfasdfasvascasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasd", - P2_FAMILYNAME, - P2_GIVENNAME, - P2_DATEOFBIRTH, - P2_PLACEOFBIRTH, - P2_BIRTHNAME); - - } catch (final Exception e) { - return; - - } - - fail("FamilyName missing input accepted"); + P2_BIRTHNAME))); } @Test public void eeTestGivenNameMissingCase() throws Exception { - try { - final SimpleEidasData result = postProcessor.postProcess( - generateInputData( - P2_eIDASID, - P2_FAMILYNAME, - null, - P2_DATEOFBIRTH, - P2_PLACEOFBIRTH, - P2_BIRTHNAME)); - - validate(result, - "asfasfasdfasdfasdfasdfasdfasvafasdfasdfasdfasdfasdfasvascasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasd", - P2_FAMILYNAME, - P2_GIVENNAME, - P2_DATEOFBIRTH, - P2_PLACEOFBIRTH, - P2_BIRTHNAME); - - } catch (final Exception e) { - return; - - } - - fail("GivenName missing input accepted"); + assertThrows("missing exception", EidasSAuthenticationException.class, + () -> postProcessor.postProcess( + generateInputData( + P2_eIDASID, + P2_FAMILYNAME, + null, + P2_DATEOFBIRTH, + P2_PLACEOFBIRTH, + P2_BIRTHNAME))); } @Test public void eeTestDateOfBirthMissingCase() throws Exception { - try { - final SimpleEidasData result = postProcessor.postProcess( - generateInputData( - P2_eIDASID, - P2_FAMILYNAME, - P2_GIVENNAME, - null, - P2_PLACEOFBIRTH, - P2_BIRTHNAME)); - - validate(result, - "asfasfasdfasdfasdfasdfasdfasvafasdfasdfasdfasdfasdfasvascasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasd", - P2_FAMILYNAME, - P2_GIVENNAME, - P2_DATEOFBIRTH, - P2_PLACEOFBIRTH, - P2_BIRTHNAME); - - } catch (final Exception e) { - return; - - } - - fail("DateOfBirth missing input accepted"); + assertThrows("missing exception", EidasSAuthenticationException.class, + () -> postProcessor.postProcess( + generateInputData( + P2_eIDASID, + P2_FAMILYNAME, + P2_GIVENNAME, + null, + P2_PLACEOFBIRTH, + P2_BIRTHNAME))); } @Test public void eeTestIdMissingCase() throws Exception { - try { - final SimpleEidasData result = postProcessor.postProcess( - generateInputData( - null, - P2_FAMILYNAME, - P2_GIVENNAME, - P2_DATEOFBIRTH, - P2_PLACEOFBIRTH, - P2_BIRTHNAME)); - - validate(result, - "asfasfasdfasdfasdfasdfasdfasvafasdfasdfasdfasdfasdfasvascasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasd", - P2_FAMILYNAME, - P2_GIVENNAME, - P2_DATEOFBIRTH, - P2_PLACEOFBIRTH, - P2_BIRTHNAME); - - } catch (final Exception e) { - return; - - } - - fail("eIDAS-Id missing input accepted"); + assertThrows("missing exception", EidasSAuthenticationException.class, + () -> postProcessor.postProcess( + generateInputData( + null, + P2_FAMILYNAME, + P2_GIVENNAME, + P2_DATEOFBIRTH, + P2_PLACEOFBIRTH, + P2_BIRTHNAME))); } private Map generateInputData(String id, String familyName, String givenName, - String dateOfBirth, String placeOfBirth, String birthName) { + String dateOfBirth, String placeOfBirth, String birthName) { final Map result = new HashMap<>(); result.put(Constants.eIDAS_ATTR_PERSONALIDENTIFIER, id); result.put(Constants.eIDAS_ATTR_CURRENTGIVENNAME, givenName); @@ -422,32 +362,15 @@ public class EidasAttributePostProcessingTest { } - private void validate(SimpleEidasData result, String id, String familyName, String givenName, - String dateOfBirth, String placeOfBirth, String birthName) { - if (!result.getPseudonym().equals(id)) { - fail(result.getPseudonym() + "is not equal to " + id); - } - - if (!result.getFamilyName().equals(familyName)) { - fail(result.getFamilyName() + "is not equal to " + familyName); - } - - if (!result.getGivenName().equals(givenName)) { - fail(result.getGivenName() + "is not equal to " + givenName); - } - - if (!result.getDateOfBirth().equals(dateOfBirth)) { - fail(result.getDateOfBirth() + "is not equal to " + dateOfBirth); - } - - if (!result.getPlaceOfBirth().equals(placeOfBirth)) { - fail(result.getPlaceOfBirth() + "is not equal to " + placeOfBirth); - } - - if (!result.getBirthName().equals(birthName)) { - fail(result.getBirthName() + "is not equal to " + birthName); - } + private void validate(SimpleEidasData result, String id, String cc, String familyName, String givenName, + String dateOfBirth, String placeOfBirth, String birthName) { + assertEquals("pseudonym", id, result.getPseudonym()); + assertEquals("countrycode", cc, result.getCitizenCountryCode()); + assertEquals("familyName", familyName, result.getFamilyName()); + assertEquals("givenName", givenName, result.getGivenName()); + assertEquals("dateOfBirth", dateOfBirth, result.getDateOfBirth()); + assertEquals("placeOfBirth", placeOfBirth, result.getPlaceOfBirth()); + assertEquals("birthName", birthName, result.getBirthName()); } - } -- cgit v1.2.3 From ea38c3b1f06263db2c03d4ee5e7b8750380009fe Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 17 May 2022 18:29:49 +0200 Subject: feat(register): inject unique transactionId as SOAP header for ZMR and SZR communication --- .../auth/eidas/v2/clients/AbstractSoapClient.java | 7 +- .../BmiSoapTransactionHeaderInterceptor.java | 87 ++++++++++++++++++++++ .../v2/test/clients/ZmrClientProductionTest.java | 3 + 3 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/BmiSoapTransactionHeaderInterceptor.java (limited to 'modules/authmodule-eIDAS-v2') diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/AbstractSoapClient.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/AbstractSoapClient.java index a039881c..20f6d2b1 100644 --- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/AbstractSoapClient.java +++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/AbstractSoapClient.java @@ -183,17 +183,20 @@ public class AbstractSoapClient { 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); + handlerList = new ArrayList<>(); } + // add unique TransactionId into SOAP header + handlerList.add(new BmiSoapTransactionHeaderInterceptor()); + // add logging handler to trace messages if required if (enableTraceLogging) { final LoggingHandler loggingHandler = new LoggingHandler(); handlerList.add(loggingHandler); } + bindingProvider.getBinding().setHandlerChain(handlerList); } } diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/BmiSoapTransactionHeaderInterceptor.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/BmiSoapTransactionHeaderInterceptor.java new file mode 100644 index 00000000..86568796 --- /dev/null +++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/BmiSoapTransactionHeaderInterceptor.java @@ -0,0 +1,87 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.clients; + +import java.util.Set; + +import javax.xml.namespace.QName; +import javax.xml.soap.SOAPElement; +import javax.xml.soap.SOAPEnvelope; +import javax.xml.soap.SOAPFactory; +import javax.xml.soap.SOAPHeader; +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.apache.commons.lang3.StringUtils; + +import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils; +import lombok.extern.slf4j.Slf4j; + + +/** + * Intercepter to set unique transactionId into Apache CXF clients. + * @author tlenz + * + */ +@Slf4j +public class BmiSoapTransactionHeaderInterceptor implements SOAPHandler { + private static final String ELEMENT = "Client-Request-Id"; + + @Override + public boolean handleMessage(SOAPMessageContext context) { + if (((Boolean) context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue()) { + if (StringUtils.isNotEmpty(TransactionIdUtils.getTransactionId())) { + injectTransactionId(context); + + } else { + log.debug("No unique transactionId. Sending message without Id ..."); + + } + } + + return true; + + } + + @Override + public boolean handleFault(SOAPMessageContext context) { + return true; + + } + + @Override + public void close(MessageContext context) { + + } + + @Override + public Set getHeaders() { + return null; + + } + + private void injectTransactionId(SOAPMessageContext context) { + try { + SOAPMessage message = context.getMessage(); + SOAPEnvelope envelope = message.getSOAPPart().getEnvelope(); + SOAPFactory soapFactory = SOAPFactory.newInstance(); + + // create header element + SOAPElement transactionIdElm = soapFactory.createElement(ELEMENT); + transactionIdElm.setTextContent(TransactionIdUtils.getTransactionId()); + + // inject header + SOAPHeader header = envelope.getHeader(); + if (header == null) { + header = envelope.addHeader(); + + } + header.addChildElement(transactionIdElm); + + } catch (Exception e) { + log.warn("Can NOT inject TransactionId into SOAP message. Sending message without Id ...", e); + + } + } + +} diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientProductionTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientProductionTest.java index cada6f40..cb9df7e5 100644 --- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientProductionTest.java +++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrClientProductionTest.java @@ -4,6 +4,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.util.List; +import java.util.UUID; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; @@ -29,6 +30,7 @@ import at.gv.bmi.namespace.zmr_su.zmr._20040201.PersonSuchenRequest; import at.gv.e_government.reference.namespace.persondata.de._20040201.NatuerlichePersonTyp; import at.gv.e_government.reference.namespace.persondata.de._20040201.PersonenNameTyp; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.impl.utils.TransactionIdUtils; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; @@ -199,6 +201,7 @@ public class ZmrClientProductionTest { @Test public void updateZmrEntryTestIdentity() throws EidasSAuthenticationException { + TransactionIdUtils.setTransactionId(UUID.randomUUID().toString()); final String personalIdentifier = "7cEYSvKZasdfsafsaf4CDVzNT4E7cjkU4Vq"; final String cc = "EE"; -- cgit v1.2.3 From 21e6b59f0a110ceb052189d63842f869d010ae3c Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 17 May 2022 18:30:32 +0200 Subject: refact(ernp): use unique transactionId without suffix for ERnP communication --- .../auth/eidas/v2/clients/ernp/ErnpRestClient.java | 31 ++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'modules/authmodule-eIDAS-v2') diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java index 6a732a0d..119a7c60 100644 --- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java +++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/ernp/ErnpRestClient.java @@ -135,7 +135,7 @@ public class ErnpRestClient implements IErnpClient { throws EidasSAuthenticationException { try { // build generic request metadata - final GenericRequestParams generic = buildGenericRequestParameters("stepId"); + final GenericRequestParams generic = buildGenericRequestParameters(); // build search request final SuchEidas eidasInfos = new SuchEidas(); @@ -177,7 +177,7 @@ public class ErnpRestClient implements IErnpClient { String citizenCountryCode) throws EidasSAuthenticationException { try { // build generic request metadata - final GenericRequestParams generic = buildGenericRequestParameters("stepMDS"); + final GenericRequestParams generic = buildGenericRequestParameters(); // build search request final Suchdaten searchInfos = new Suchdaten(); @@ -218,7 +218,7 @@ public class ErnpRestClient implements IErnpClient { try { // build generic request metadata - final GenericRequestParams generic = buildGenericRequestParameters("stepCC"); + final GenericRequestParams generic = buildGenericRequestParameters(); // build search request final PersonSuchen personSuchen = new PersonSuchen(); @@ -291,7 +291,7 @@ public class ErnpRestClient implements IErnpClient { public ErnpRegisterResult add(SimpleEidasData eidData) throws EidasSAuthenticationException { try { // build generic request metadata - final GenericRequestParams generic = buildGenericRequestParameters("stepNew"); + final GenericRequestParams generic = buildGenericRequestParameters(); // build update request PersonAnlegen ernpReq = new PersonAnlegen(); @@ -459,7 +459,7 @@ public class ErnpRestClient implements IErnpClient { Collection eidasDocumentToAdd, SimpleEidasData mdsToUpdate, String citizenCountryCode) throws ServiceFault { // build generic request metadata - final GenericRequestParams generic = buildGenericRequestParameters("stepKittUpdate"); + final GenericRequestParams generic = buildGenericRequestParameters(); // build update request PersonAendern ernpReq = new PersonAendern(); @@ -562,7 +562,7 @@ public class ErnpRestClient implements IErnpClient { private Person searchPersonForUpdate(RegisterResult registerResult) throws WorkflowException { // build generic request metadata - final GenericRequestParams generic = buildGenericRequestParameters("stepKittSearch"); + final GenericRequestParams generic = buildGenericRequestParameters(); // build search request final Suchdaten searchInfos = new Suchdaten(); @@ -762,10 +762,25 @@ public class ErnpRestClient implements IErnpClient { final RestTemplate springClient = new RestTemplate(requestFactory); springClient.setErrorHandler(buildErrorHandler()); springClient.getMessageConverters().add(0, buildCustomJacksonObjectMapper()); + //springClient.getInterceptors().add(buildTransactionIdInterceptor()); return springClient; } + + //private ClientHttpRequestInterceptor buildTransactionIdInterceptor() { + // return new ClientHttpRequestInterceptor() { + // + // @Override + // public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) + // throws IOException { + // request.getHeaders().add("dfafsafafsaf", TransactionIdUtils.getTransactionId()); + // return execution.execute(request, body); + // + // } + // }; + //} + private HttpMessageConverter buildCustomJacksonObjectMapper() { final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON)); @@ -833,13 +848,13 @@ public class ErnpRestClient implements IErnpClient { } - private GenericRequestParams buildGenericRequestParameters(String operationIdentifier) { + private GenericRequestParams buildGenericRequestParameters() { return GenericRequestParams.builder() .clientBehkz(basicConfig.getBasicConfiguration( Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_REQ_ORGANIZATION_NR)) .clientName(MessageFormat.format(Constants.CLIENT_INFO, versionHolder.getVersion())) .clientRequestTime(OffsetDateTime.now()) - .clientRequestId(TransactionIdUtils.getTransactionId() + "_" + operationIdentifier) + .clientRequestId(TransactionIdUtils.getTransactionId()) .build(); } -- cgit v1.2.3 From ac8b7edeefc1850fdcab859ee6f544aa4f614471 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Tue, 17 May 2022 18:41:50 +0200 Subject: test(eidas): fix broken test that checks post-processing for greece specific data --- .../auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/authmodule-eIDAS-v2') diff --git a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java index 867eac4a..16efd84b 100644 --- a/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java +++ b/modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/validation/EidasAttributePostProcessingTest.java @@ -261,7 +261,7 @@ public class EidasAttributePostProcessingTest { validate(result, P8_eIDASID_PID, - "GR", + "EL", P8_FAMILYNAME, P8_GIVENNAME, P8_DATEOFBIRTH, -- cgit v1.2.3