diff options
Diffstat (limited to 'modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas')
4 files changed, 142 insertions, 20 deletions
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<Handler> 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<SOAPMessageContext> { + 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<QName> 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/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<? extends Eidas> 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(); } 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 <code>true</code> if the current state is valid, otherwise <code>false</code> * @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); } |