diff options
| author | Christian Kollmann <christian.kollmann@a-sit.at> | 2021-02-22 15:46:10 +0100 | 
|---|---|---|
| committer | Christian Kollmann <christian.kollmann@a-sit.at> | 2021-02-22 15:46:10 +0100 | 
| commit | 3338a3dd00fabf28f1de8579535b1626dbe99908 (patch) | |
| tree | 82065cd76ba01552c80fc178a9c39a33d69bb850 /eidas_modules/authmodule-eIDAS-v2/src | |
| parent | 87e5fa9dd9966d427e45e36b9c3530b3c28d1f32 (diff) | |
| download | National_eIDAS_Gateway-3338a3dd00fabf28f1de8579535b1626dbe99908.tar.gz National_eIDAS_Gateway-3338a3dd00fabf28f1de8579535b1626dbe99908.tar.bz2 National_eIDAS_Gateway-3338a3dd00fabf28f1de8579535b1626dbe99908.zip | |
Refactor tasks for MobilePhoneSignature login
Diffstat (limited to 'eidas_modules/authmodule-eIDAS-v2/src')
5 files changed, 378 insertions, 445 deletions
| diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateMobilePhoneSignatureRequestTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateMobilePhoneSignatureRequestTask.java index 4d305c7d..e6484e63 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateMobilePhoneSignatureRequestTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateMobilePhoneSignatureRequestTask.java @@ -23,16 +23,6 @@  package at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks; -import java.text.MessageFormat; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang3.StringUtils; -import org.opensaml.saml.saml2.metadata.EntityDescriptor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -  import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.IdAustriaClientAuthConstants;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.IdAustriaClientAuthRequestBuilderConfiguration; @@ -42,15 +32,28 @@ 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.api.storage.ITransactionStorage;  import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +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.modules.AbstractAuthServletTask;  import at.gv.egiz.eaaf.core.impl.utils.Random; +import at.gv.egiz.eaaf.modules.pvp2.exception.CredentialsNotAvailableException;  import at.gv.egiz.eaaf.modules.pvp2.sp.impl.PvpAuthnRequestBuilder;  import lombok.extern.slf4j.Slf4j; +import net.shibboleth.utilities.java.support.resolver.ResolverException;  import net.shibboleth.utilities.java.support.security.SecureRandomIdentifierGenerationStrategy; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.opensaml.saml.saml2.metadata.EntityDescriptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.text.MessageFormat;  /**   * Generate a SAML2 AuthnRequest to authenticate the user at ID Austria system. + * This corresponds to Step 15A in the eIDAS Matching Concept.   *   * @author tlenz   */ @@ -77,55 +80,66 @@ public class GenerateMobilePhoneSignatureRequestTask extends AbstractAuthServlet        throws TaskExecutionException {      try {        log.trace("Starting GenerateMobilePhoneSignatureRequestTask"); -      //step 15a - -      // get entityID for ms-specific ID Austria node -      final String msNodeEntityID = basicConfig.getBasicConfiguration( -          IdAustriaClientAuthConstants.CONFIG_PROPS_ID_AUSTRIA_ENTITYID); - -      if (StringUtils.isEmpty(msNodeEntityID)) { -        log.warn("ID Austria authentication not possible -> NO EntityID for ID Austria System FOUND!");         -        throw new EaafConfigurationException(Constants.ERRORCODE_00, -            new Object[]{IdAustriaClientAuthConstants.CONFIG_PROPS_ID_AUSTRIA_ENTITYID});         - -      } - -      // load IDP SAML2 entitydescriptor -      final EntityDescriptor entityDesc = metadataService.getEntityDescriptor(msNodeEntityID); -      if (entityDesc == null) { -        throw new EaafConfigurationException(IdAustriaClientAuthConstants.ERRORCODE_02, -            new Object[]{MessageFormat.format(ERROR_MSG_1, msNodeEntityID)}); - -      } +      final String entityId = loadEntityId(); +      final EntityDescriptor entityDesc = loadEntityDescriptor(entityId); +      final IdAustriaClientAuthRequestBuilderConfiguration authnReqConfig = buildAuthnRequestConfig(entityDesc); +      final String relayState = buildRelayState(); +      authnReqBuilder.buildAuthnRequest(pendingReq, authnReqConfig, relayState, response); // also transmits! +    } catch (final Exception e) { +      throw new TaskExecutionException(pendingReq, "Generation of SAML2 AuthnRequest to ID Austria System FAILED", e); +    } +  } -      // setup AuthnRequestBuilder configuration -      final IdAustriaClientAuthRequestBuilderConfiguration authnReqConfig = -          new IdAustriaClientAuthRequestBuilderConfiguration(); -      final SecureRandomIdentifierGenerationStrategy gen = -          new SecureRandomIdentifierGenerationStrategy(); -      authnReqConfig.setRequestId(gen.generateIdentifier()); -      authnReqConfig.setIdpEntity(entityDesc); -      authnReqConfig.setPassive(false); -      authnReqConfig.setSignCred(credential.getMessageSigningCredential()); -      authnReqConfig.setSpEntityID( -          pendingReq.getAuthUrlWithOutSlash() + IdAustriaClientAuthConstants.ENDPOINT_METADATA); -      authnReqConfig.setRequestedLoA(authConfig.getBasicConfiguration( -          IdAustriaClientAuthConstants.CONFIG_PROPS_REQUIRED_LOA, -          IdAustriaClientAuthConstants.CONFIG_DEFAULT_LOA_EIDAS_LEVEL)); +  @NotNull +  private String loadEntityId() throws EaafConfigurationException { +    final String msNodeEntityID = basicConfig.getBasicConfiguration( +        IdAustriaClientAuthConstants.CONFIG_PROPS_ID_AUSTRIA_ENTITYID); +    if (StringUtils.isEmpty(msNodeEntityID)) { +      log.warn("ID Austria authentication not possible -> NO EntityID for ID Austria System FOUND!"); +      throw new EaafConfigurationException(Constants.ERRORCODE_00, +          new Object[]{IdAustriaClientAuthConstants.CONFIG_PROPS_ID_AUSTRIA_ENTITYID}); +    } +    return msNodeEntityID; +  } -      /*build relayState for session synchronization, because SAML2 only allows RelayState with 80 characters -       * but encrypted PendingRequestId is much longer. -       */ -      String relayState = Random.nextProcessReferenceValue(); -      transactionStorage.put(relayState, pendingReq.getPendingRequestId(), -1); +  /** +   * Build relayState for session synchronization, because SAML2 only allows RelayState with 80 characters +   * but encrypted PendingRequestId is much longer. +   */ +  @NotNull +  private String buildRelayState() throws EaafException { +    String relayState = Random.nextProcessReferenceValue(); +    transactionStorage.put(relayState, pendingReq.getPendingRequestId(), -1); +    return relayState; +  } -      // build and transmit AuthnRequest -      authnReqBuilder.buildAuthnRequest(pendingReq, authnReqConfig, relayState, response); +  @NotNull +  private EntityDescriptor loadEntityDescriptor(String msNodeEntityID) +      throws ResolverException, EaafConfigurationException { +    final EntityDescriptor entityDesc = metadataService.getEntityDescriptor(msNodeEntityID); +    if (entityDesc == null) { +      throw new EaafConfigurationException(IdAustriaClientAuthConstants.ERRORCODE_02, +          new Object[]{MessageFormat.format(ERROR_MSG_1, msNodeEntityID)}); -    } catch (final Exception e) { -      throw new TaskExecutionException(pendingReq,  -          "Generation of SAML2 AuthnRequest to ID Austria System FAILED", e); -            } +    return entityDesc; +  } + +  @NotNull +  private IdAustriaClientAuthRequestBuilderConfiguration buildAuthnRequestConfig(EntityDescriptor entityDesc) +      throws CredentialsNotAvailableException { +    final IdAustriaClientAuthRequestBuilderConfiguration authnReqConfig = +        new IdAustriaClientAuthRequestBuilderConfiguration(); +    final SecureRandomIdentifierGenerationStrategy gen = new SecureRandomIdentifierGenerationStrategy(); +    authnReqConfig.setRequestId(gen.generateIdentifier()); +    authnReqConfig.setIdpEntity(entityDesc); +    authnReqConfig.setPassive(false); +    authnReqConfig.setSignCred(credential.getMessageSigningCredential()); +    authnReqConfig.setSpEntityID( +        pendingReq.getAuthUrlWithOutSlash() + IdAustriaClientAuthConstants.ENDPOINT_METADATA); +    authnReqConfig.setRequestedLoA(authConfig.getBasicConfiguration( +        IdAustriaClientAuthConstants.CONFIG_PROPS_REQUIRED_LOA, +        IdAustriaClientAuthConstants.CONFIG_DEFAULT_LOA_EIDAS_LEVEL)); +    return authnReqConfig;    }  } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask.java index 09f2d54c..81be04b5 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask.java @@ -58,6 +58,7 @@ import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AuthnResponseValidationExceptio  import at.gv.egiz.eaaf.modules.pvp2.sp.impl.utils.AssertionAttributeExtractor;  import lombok.extern.slf4j.Slf4j;  import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull;  import org.opensaml.core.xml.io.MarshallingException;  import org.opensaml.messaging.decoder.MessageDecodingException;  import org.opensaml.saml.saml2.core.Response; @@ -70,12 +71,16 @@ import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletResponse;  import javax.xml.transform.TransformerException;  import java.io.IOException; -import java.util.HashMap;  import java.util.List;  import java.util.Set; +import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.DATA_INITIAL_REGISTER_RESULT; +import static at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants.DATA_SIMPLE_EIDAS; +import static at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING; +  /**   * Task that receives the SAML2 response from ID Austria system. + * This corresponds to Step 15 in the eIDAS Matching Concept.   *   * @author tlenz   */ @@ -89,7 +94,7 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask extends    private RegisterSearchService registerSearchService;    @Autowired    private IdAustriaClientAuthCredentialProvider credentialProvider; -  @Autowired(required = true) +  @Autowired    IdAustriaClientAuthMetadataProvider metadataProvider;    private static final String ERROR_PVP_03 = "sp.pvp2.03"; @@ -100,208 +105,177 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask extends    private static final String ERROR_PVP_11 = "sp.pvp2.11";    private static final String ERROR_PVP_12 = "sp.pvp2.12"; -  private static final String ERROR_MSG_00 = -      "Receive INVALID PVP Response from ID Austria system"; -  private static final String ERROR_MSG_01 = -      "Processing PVP response from 'ID Austria system' FAILED."; -  private static final String ERROR_MSG_02 = -      "PVP response decrytion FAILED. No credential found."; -  private static final String ERROR_MSG_03 = -      "PVP response validation FAILED."; +  private static final String ERROR_MSG_00 = "Receive INVALID PVP Response from ID Austria system"; +  private static final String ERROR_MSG_01 = "Processing PVP response from 'ID Austria system' FAILED."; +  private static final String ERROR_MSG_02 = "PVP response decrytion FAILED. No credential found."; +  private static final String ERROR_MSG_03 = "PVP response validation FAILED.";    @Override    public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)        throws TaskExecutionException {      try { -      log.trace("Starting ReceiveMobilePhoneSignatureResponseTask");//Node 15 -      InboundMessage msg = null; -      IDecoder decoder = null; -      EaafUriCompare comperator = null; - -      // select Response Binding -      if (request.getMethod().equalsIgnoreCase("POST")) { -        decoder = new PostBinding(); -        comperator = new EaafUriCompare(pendingReq.getAuthUrl() + IdAustriaClientAuthConstants.ENDPOINT_POST); -        log.trace("Receive PVP Response from 'ID Austria system', by using POST-Binding."); - -      } else if (request.getMethod().equalsIgnoreCase("GET")) { -        decoder = new RedirectBinding(); -        comperator = new EaafUriCompare(pendingReq.getAuthUrl() -            + IdAustriaClientAuthConstants.ENDPOINT_REDIRECT); -        log.trace("Receive PVP Response from 'ID Austria system', by using Redirect-Binding."); - -      } else { -        log.warn("Receive PVP Response, but Binding (" -            + request.getMethod() + ") is not supported."); -        throw new AuthnResponseValidationException(ERROR_PVP_03, new Object[]{ -            IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING}); - -      } - -      // decode PVP response object -      msg = (InboundMessage) decoder.decode( -          request, response, metadataProvider, IDPSSODescriptor.DEFAULT_ELEMENT_NAME, -          comperator); - -      // validate response signature -      if (!msg.isVerified()) { -        samlVerificationEngine.verify(msg, TrustEngineFactory.getSignatureKnownKeysTrustEngine( -            metadataProvider)); -        msg.setVerified(true); - -      } - -      // validate assertion -      final Pair<PvpSProfileResponse, Boolean> processedMsg = -          preProcessAuthResponse((PvpSProfileResponse) msg); - -      //check if SAML2 response contains user-stop decision +      log.trace("Starting ReceiveMobilePhoneSignatureResponseTask"); +      IDecoder decoder = loadDecoder(request); +      EaafUriCompare comparator = loadComparator(request); +      InboundMessage inboundMessage = decodeAndVerifyMessage(request, response, decoder, comparator); +      final Pair<PvpSProfileResponse, Boolean> processedMsg = validateAssertion((PvpSProfileResponse) inboundMessage);        if (processedMsg.getSecond()) {          stopProcessFromUserDecision(executionContext, request, response); +        return; +      } -      } else { -        // validate entityId of response -        final String msNodeEntityID = authConfig.getBasicConfiguration( -            IdAustriaClientAuthConstants.CONFIG_PROPS_ID_AUSTRIA_ENTITYID); -        final String respEntityId = msg.getEntityID(); -        if (!msNodeEntityID.equals(respEntityId)) { -          log.warn("Response Issuer is not from valid 'ID Austria IDP'. Stopping ID Austria authentication ..."); -          throw new AuthnResponseValidationException(ERROR_PVP_08, -              new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING, -                  msg.getEntityID()}); - -        } - -        // initialize Attribute extractor -        final AssertionAttributeExtractor extractor = -            new AssertionAttributeExtractor(processedMsg.getFirst().getResponse()); - - - - -        /* -         * SAML2 response ist bereits vollständig validiert und die Attribute können aus dem -         * <AssertionAttributeExtractor extractor> ausgelesen werden. -         * Die AttributeNamen sind entsprechend PVP Spezifikation, z.B. PvpAttributeDefinitions.GIVEN_NAME_NAME -         * -         * --------------------------------------------------------------------------------------------- -         * -         * TODO: ab hier müssen wir wohl was anpassen -         * -         */ - -        //load additional search-data from pendingRequest -        final AuthProcessDataWrapper authProcessData = pendingReq.getSessionData(AuthProcessDataWrapper.class); -        MergedRegisterSearchResult initialSearchResult = -            authProcessData.getGenericDataFromSession(Constants.DATA_INITIAL_REGISTER_RESULT, -                MergedRegisterSearchResult.class); -        SimpleEidasData eidData = authProcessData.getGenericDataFromSession(Constants.DATA_SIMPLE_EIDAS, -            SimpleEidasData.class); - - -        SimpleMobileSignatureData simpleMobileSignatureData = -            getAuthDataFromInterfederation(extractor, authProcessData); -        if (!simpleMobileSignatureData.equalsSimpleEidasData(eidData)) { -          //User cheated? -          throw new InvalidUserInputException();//TODO -        } -        String bpkzp = simpleMobileSignatureData.getBpk(); - -        MergedRegisterSearchResult result = registerSearchService.searchWithBpkZp(bpkzp); -        if (result.getResultCount() == 0) { -          //go to step 16 -          executionContext.put(Constants.TRANSITION_TO_GENERATE_GUI_QUERY_AUSTRIAN_RESIDENCE_TASK, true); -          return; -        } else if (result.getResultCount() == 1) { -          String bpk = registerSearchService.step7aKittProcess(initialSearchResult, result, eidData, pendingReq); -          authProcessData.setGenericDataToSession(Constants.DATA_RESULT_MATCHING_BPK, bpk); -          //node 110 -        } else if (result.getResultCount() > 1) { -          throw new ManualFixNecessaryException("bpkzp:" + bpkzp);// node 108 -        } - -        // set NeedConsent to false, because user gives consont during authentication -        pendingReq.setNeedUserConsent(false); - -        log.info("Receive a valid assertion from IDP " + msg.getEntityID()); +      validateEntityId(inboundMessage); +      AssertionAttributeExtractor extractor = new AssertionAttributeExtractor(processedMsg.getFirst().getResponse()); + +      /* +       * SAML2 response ist bereits vollständig validiert und die Attribute können aus dem +       * <AssertionAttributeExtractor extractor> ausgelesen werden. +       * Die AttributeNamen sind entsprechend PVP Spezifikation, z.B. PvpAttributeDefinitions.GIVEN_NAME_NAME +       * +       * --------------------------------------------------------------------------------------------- +       * +       * TODO: ab hier müssen wir wohl was anpassen +       * +       */ + +      final AuthProcessDataWrapper authProcessData = pendingReq.getSessionData(AuthProcessDataWrapper.class); +      MergedRegisterSearchResult initialSearchResult = +          authProcessData.getGenericDataFromSession(DATA_INITIAL_REGISTER_RESULT, MergedRegisterSearchResult.class); +      SimpleEidasData eidasData = authProcessData.getGenericDataFromSession(DATA_SIMPLE_EIDAS, SimpleEidasData.class); + +      SimpleMobileSignatureData simpleMobileSignatureData = getAuthDataFromInterfederation(extractor, authProcessData); +      if (!simpleMobileSignatureData.equalsSimpleEidasData(eidasData)) { +        //TODO User has cheated? +        throw new InvalidUserInputException(); +      } +      String bpkZp = simpleMobileSignatureData.getBpk(); +      MergedRegisterSearchResult result = registerSearchService.searchWithBpkZp(bpkZp); +      if (result.getResultCount() == 0) { +        //go to step 16 +        executionContext.put(Constants.TRANSITION_TO_GENERATE_GUI_QUERY_AUSTRIAN_RESIDENCE_TASK, true); +        return; +      } else if (result.getResultCount() == 1) { +        String bpk = registerSearchService.step7aKittProcess(initialSearchResult, result, eidasData, pendingReq); +        authProcessData.setGenericDataToSession(Constants.DATA_RESULT_MATCHING_BPK, bpk); +        return; +        //node 110 +      } else if (result.getResultCount() > 1) { +        throw new ManualFixNecessaryException("bpkZp: " + bpkZp);// node 108        } +      // set NeedConsent to false, because user gives consent during authentication +      pendingReq.setNeedUserConsent(false); +      log.info("Receive a valid assertion from IDP " + inboundMessage.getEntityID());      } catch (final AuthnResponseValidationException e) {        throw new TaskExecutionException(pendingReq, ERROR_MSG_03, e); -      } catch (MessageDecodingException | SecurityException | SamlSigningException e) {        //final String samlRequest = request.getParameter("SAMLRequest");        //log.debug("Receive INVALID PVP Response from 'ms-specific eIDAS node': {}",        //    samlRequest, null, e);        throw new TaskExecutionException(pendingReq, ERROR_MSG_00, -          new AuthnResponseValidationException(ERROR_PVP_11, -              new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING}, e)); - +          new AuthnResponseValidationException(ERROR_PVP_11, new Object[]{MODULE_NAME_FOR_LOGGING}, e));      } catch (IOException | MarshallingException | TransformerException e) {        log.debug("Processing PVP response from 'ms-specific eIDAS node' FAILED.", e);        throw new TaskExecutionException(pendingReq, ERROR_MSG_01, -          new AuthnResponseValidationException(ERROR_PVP_12, -              new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING, e.getMessage()}, -              e)); - +          new AuthnResponseValidationException(ERROR_PVP_12, new Object[]{MODULE_NAME_FOR_LOGGING, e.getMessage()}, e));      } catch (final CredentialsNotAvailableException e) {        log.debug("PVP response decrytion FAILED. No credential found.", e);        throw new TaskExecutionException(pendingReq, ERROR_MSG_02, -          new AuthnResponseValidationException(ERROR_PVP_10, -              new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING}, e)); - +          new AuthnResponseValidationException(ERROR_PVP_10, new Object[]{MODULE_NAME_FOR_LOGGING}, e));      } catch (final Exception e) {        e.printStackTrace();        log.debug("PVP response validation FAILED. Msg:" + e.getMessage(), e);        throw new TaskExecutionException(pendingReq, ERROR_MSG_03, -          new AuthnResponseValidationException(ERROR_PVP_12, -              new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING, e.getMessage()}, e)); +          new AuthnResponseValidationException(ERROR_PVP_12, new Object[]{MODULE_NAME_FOR_LOGGING, e.getMessage()}, e)); +    } +  } + +  @NotNull +  private InboundMessage decodeAndVerifyMessage(HttpServletRequest request, HttpServletResponse response, +                                                IDecoder decoder, EaafUriCompare comparator) throws Exception { +    InboundMessage inboundMessage = (InboundMessage) decoder.decode(request, response, metadataProvider, +        IDPSSODescriptor.DEFAULT_ELEMENT_NAME, comparator); +    if (!inboundMessage.isVerified()) { +      samlVerificationEngine.verify(inboundMessage, TrustEngineFactory.getSignatureKnownKeysTrustEngine( +          metadataProvider)); +      inboundMessage.setVerified(true); +    } +    return inboundMessage; +  } + +  private void validateEntityId(InboundMessage inboundMessage) throws AuthnResponseValidationException { +    final String msNodeEntityID = authConfig +        .getBasicConfiguration(IdAustriaClientAuthConstants.CONFIG_PROPS_ID_AUSTRIA_ENTITYID); +    final String respEntityId = inboundMessage.getEntityID(); +    if (!msNodeEntityID.equals(respEntityId)) { +      log.warn("Response Issuer is not from valid 'ID Austria IDP'. Stopping ID Austria authentication ..."); +      throw new AuthnResponseValidationException(ERROR_PVP_08, +          new Object[]{MODULE_NAME_FOR_LOGGING, +              inboundMessage.getEntityID()}); +    } +  } + +  @NotNull +  private EaafUriCompare loadComparator(HttpServletRequest request) throws AuthnResponseValidationException { +    if (request.getMethod().equalsIgnoreCase("POST")) { +      log.trace("Receive PVP Response from 'ID Austria system', by using POST-Binding."); +      return new EaafUriCompare(pendingReq.getAuthUrl() + IdAustriaClientAuthConstants.ENDPOINT_POST); +    } else if (request.getMethod().equalsIgnoreCase("GET")) { +      log.trace("Receive PVP Response from 'ID Austria system', by using Redirect-Binding."); +      return new EaafUriCompare(pendingReq.getAuthUrl() + IdAustriaClientAuthConstants.ENDPOINT_REDIRECT); +    } else { +      log.warn("Receive PVP Response from 'ID Austria system', but Binding {} is not supported.", request.getMethod()); +      throw new AuthnResponseValidationException(ERROR_PVP_03, new Object[]{MODULE_NAME_FOR_LOGGING});      } +  } +  @NotNull +  private IDecoder loadDecoder(HttpServletRequest request) throws AuthnResponseValidationException { +    if (request.getMethod().equalsIgnoreCase("POST")) { +      log.trace("Receive PVP Response from 'ID Austria system', by using POST-Binding."); +      return new PostBinding(); +    } else if (request.getMethod().equalsIgnoreCase("GET")) { +      log.trace("Receive PVP Response from 'ID Austria system', by using Redirect-Binding."); +      return new RedirectBinding(); +    } else { +      log.warn("Receive PVP Response from 'ID Austria system', but Binding {} is not supported.", request.getMethod()); +      throw new AuthnResponseValidationException(ERROR_PVP_03, new Object[]{MODULE_NAME_FOR_LOGGING}); +    }    } -  private Pair<PvpSProfileResponse, Boolean> preProcessAuthResponse(PvpSProfileResponse msg) +  private Pair<PvpSProfileResponse, Boolean> validateAssertion(PvpSProfileResponse msg)        throws IOException, MarshallingException, TransformerException,        CredentialsNotAvailableException, AuthnResponseValidationException, SamlAssertionValidationExeption {      log.debug("Start PVP21 assertion processing... "); -    final Response samlResp = (Response) msg.getResponse(); - -    // check SAML2 response status-code -    if (samlResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS)) { -      // validate PVP 2.1 assertion -      samlVerificationEngine.validateAssertion(samlResp, +    final Response response = (Response) msg.getResponse(); +    if (response.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS)) { +      samlVerificationEngine.validateAssertion(response,            credentialProvider.getMessageEncryptionCredential(),            pendingReq.getAuthUrl() + IdAustriaClientAuthConstants.ENDPOINT_METADATA, -          IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING); - -      msg.setSamlMessage(Saml2Utils.asDomDocument(samlResp).getDocumentElement()); +          MODULE_NAME_FOR_LOGGING); +      msg.setSamlMessage(Saml2Utils.asDomDocument(response).getDocumentElement());        revisionsLogger.logEvent(pendingReq,            IdAustriaClientAuthEventConstants.AUTHPROCESS_ID_AUSTRIA_RESPONSE_RECEIVED, -          samlResp.getID()); +          response.getID());        return Pair.newInstance(msg, false); -      } else { -      log.info("Receive StatusCode {} from 'ms-specific eIDAS node'.", -          samlResp.getStatus().getStatusCode().getValue()); -      StatusCode subStatusCode = getSubStatusCode(samlResp); +      log.info("Receive StatusCode {} from 'ms-specific eIDAS node'.", response.getStatus().getStatusCode().getValue()); +      StatusCode subStatusCode = getSubStatusCode(response);        if (subStatusCode != null            && IdAustriaClientAuthConstants.SAML2_STATUSCODE_USERSTOP.equals(subStatusCode.getValue())) {          log.info("Find 'User-Stop operation' in SAML2 response. Stopping authentication process ... ");          return Pair.newInstance(msg, true); -        }        revisionsLogger.logEvent(pendingReq,            IdAustriaClientAuthEventConstants.AUTHPROCESS_ID_AUSTRIA_RESPONSE_RECEIVED_ERROR);        throw new AuthnResponseValidationException(ERROR_PVP_05, -          new Object[]{IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING, -              samlResp.getIssuer().getValue(), -              samlResp.getStatus().getStatusCode().getValue(), -              samlResp.getStatus().getStatusMessage().getMessage()}); - +          new Object[]{MODULE_NAME_FOR_LOGGING, +              response.getIssuer().getValue(), +              response.getStatus().getStatusCode().getValue(), +              response.getStatus().getStatusMessage().getMessage()});      } -    }    /** @@ -315,55 +289,42 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask extends          && StringUtils.isNotEmpty(samlResp.getStatus().getStatusCode().getStatusCode().getValue())) {        return samlResp.getStatus().getStatusCode().getStatusCode();      } -      return null;    }    private SimpleMobileSignatureData getAuthDataFromInterfederation(AssertionAttributeExtractor extractor,                                                                     AuthProcessDataWrapper authProcessData)        throws EaafBuilderException { -      List<String> requiredAttributes = IdAustriaClientAuthConstants.DEFAULT_REQUIRED_PVP_ATTRIBUTE_NAMES; -    SimpleMobileSignatureData simpleMobileSignatureData = new SimpleMobileSignatureData(); +    SimpleMobileSignatureData result = new SimpleMobileSignatureData();      try { -      // check if all attributes are include        if (!extractor.containsAllRequiredAttributes(requiredAttributes)) {          log.warn("PVP Response from 'ID Austria node' contains not all requested attributes."); -        throw new AssertionValidationExeption(ERROR_PVP_06, new Object[]{ -            IdAustriaClientAuthConstants.MODULE_NAME_FOR_LOGGING}); - +        throw new AssertionValidationExeption(ERROR_PVP_06, new Object[]{MODULE_NAME_FOR_LOGGING});        } - -      HashMap<String, String> map = new HashMap<>();        final Set<String> includedAttrNames = extractor.getAllIncludeAttributeNames();        for (final String attrName : includedAttrNames) { -        map.put(attrName, extractor.getSingleAttributeValue(attrName)); -          if (PvpAttributeDefinitions.BPK_NAME.equals(attrName)) { -          simpleMobileSignatureData.setBpk(extractor.getSingleAttributeValue(attrName)); +          result.setBpk(extractor.getSingleAttributeValue(attrName));          }          if (PvpAttributeDefinitions.GIVEN_NAME_NAME.equals(attrName)) { -          simpleMobileSignatureData.setGivenName(extractor.getSingleAttributeValue(attrName)); +          result.setGivenName(extractor.getSingleAttributeValue(attrName));          }          if (PvpAttributeDefinitions.PRINCIPAL_NAME_NAME.equals(attrName)) { -          simpleMobileSignatureData.setFamilyName(extractor.getSingleAttributeValue(attrName)); +          result.setFamilyName(extractor.getSingleAttributeValue(attrName));          }          if (PvpAttributeDefinitions.BIRTHDATE_NAME.equals(attrName)) { -          simpleMobileSignatureData.setDateOfBirth(extractor.getSingleAttributeValue(attrName)); +          result.setDateOfBirth(extractor.getSingleAttributeValue(attrName));          }          if (PvpAttributeDefinitions.EID_CITIZEN_EIDAS_QAA_LEVEL_NAME.equals(attrName)) {            authProcessData.setQaaLevel(extractor.getSingleAttributeValue(attrName));          } -        } -        authProcessData.setIssueInstant(extractor.getAssertionIssuingDate()); -      } catch (final AssertionValidationExeption e) {        throw new EaafBuilderException(ERROR_PVP_06, null, e.getMessage(), e); -      } -    return simpleMobileSignatureData; +    return result;    } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/dummy/DummyOA.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/dummy/DummyOA.java index cf879562..2f7782ae 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/dummy/DummyOA.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/dummy/DummyOA.java @@ -1,21 +1,15 @@  package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.dummy; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; -  import at.gv.egiz.eaaf.core.impl.data.Pair;  import at.gv.egiz.eaaf.core.impl.idp.auth.builder.BpkBuilder;  import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; -  import lombok.Getter;  import lombok.Setter; +import org.apache.commons.lang3.StringUtils; + +import java.util.*; -public class DummyOA implements IAhSpConfiguration{ +public class DummyOA implements IAhSpConfiguration {    private static final long serialVersionUID = 1L;    private String uniqueAppId = null; @@ -74,7 +68,7 @@ public class DummyOA implements IAhSpConfiguration{    @Override    public boolean isConfigurationValue(final String key) {      if (StringUtils.isNotEmpty(getConfigurationValue(key))) { -      return Boolean.valueOf(getConfigurationValue(key)); +      return Boolean.parseBoolean(getConfigurationValue(key));      } else {        return false;      } @@ -258,7 +252,7 @@ public class DummyOA implements IAhSpConfiguration{    @Override    public boolean isRestrictedServiceProvider() { -    return this.restricted ; +    return this.restricted;    } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateMobilePhoneSignatureRequestTaskTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateMobilePhoneSignatureRequestTaskTest.java index 4fb05a35..8e5ecfe1 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateMobilePhoneSignatureRequestTaskTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/GenerateMobilePhoneSignatureRequestTaskTest.java @@ -1,31 +1,5 @@  package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.tasks; -import static org.junit.Assert.assertThrows; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.Base64; -import java.util.Map; - -import org.apache.commons.lang3.RandomStringUtils; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport; -import org.opensaml.core.xml.util.XMLObjectSupport; -import org.opensaml.saml.common.xml.SAMLConstants; -import org.opensaml.saml.saml2.core.AuthnRequest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; -  import at.asitplus.eidas.specific.connector.test.config.dummy.MsConnectorDummyConfigMap;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.IdAustriaClientAuthConstants;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.idaustriaclient.provider.IdAustriaClientAuthMetadataProvider; @@ -48,6 +22,34 @@ import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xIniti  import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;  import at.gv.egiz.eaaf.modules.pvp2.impl.validation.TrustEngineFactory;  import at.gv.egiz.eaaf.modules.pvp2.impl.verification.SamlVerificationEngine; +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport; +import org.opensaml.core.xml.util.XMLObjectSupport; +import org.opensaml.saml.common.xml.SAMLConstants; +import org.opensaml.saml.saml2.core.AuthnRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Base64; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; +import static org.springframework.util.Assert.isInstanceOf;  @RunWith(SpringJUnit4ClassRunner.class)  @ContextConfiguration(locations = { @@ -140,13 +142,10 @@ public class GenerateMobilePhoneSignatureRequestTaskTest {      final TaskExecutionException e = assertThrows(TaskExecutionException.class,          () -> task.execute(pendingReq, executionContext)); -    Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -    Assert.assertNotNull(e.getOriginalException()); -    org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class, -        e.getOriginalException()); -    Assert.assertEquals("module.eidasauth.00", -        ((EaafConfigurationException) e.getOriginalException()).getErrorId()); -     +    assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +    assertNotNull(e.getOriginalException()); +    isInstanceOf(EaafConfigurationException.class, e.getOriginalException()); +    assertEquals("module.eidasauth.00", ((EaafConfigurationException) e.getOriginalException()).getErrorId());    }    @Test @@ -156,14 +155,12 @@ public class GenerateMobilePhoneSignatureRequestTaskTest {      final TaskExecutionException e = assertThrows(TaskExecutionException.class,          () -> task.execute(pendingReq, executionContext)); -    Assert.assertNotNull(e.getPendingRequestID()); -    Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -    Assert.assertNotNull(e.getOriginalException()); -    org.springframework.util.Assert.isInstanceOf(EaafConfigurationException.class, -        e.getOriginalException()); -    Assert.assertEquals("module.eidasauth.idaustria.02", +    assertNotNull(e.getPendingRequestID()); +    assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +    assertNotNull(e.getOriginalException()); +    isInstanceOf(EaafConfigurationException.class, e.getOriginalException()); +    assertEquals("module.eidasauth.idaustria.02",          ((EaafConfigurationException) e.getOriginalException()).getErrorId()); -    }    @Test @@ -175,14 +172,12 @@ public class GenerateMobilePhoneSignatureRequestTaskTest {      final TaskExecutionException e = assertThrows(TaskExecutionException.class,          () -> task.execute(pendingReq, executionContext)); -    Assert.assertNotNull(e.getPendingRequestID()); -    Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -    Assert.assertNotNull(e.getOriginalException()); -    org.springframework.util.Assert.isInstanceOf(CredentialsNotAvailableException.class, -        e.getOriginalException()); -    Assert.assertEquals("internal.pvp.01", +    assertNotNull(e.getPendingRequestID()); +    assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +    assertNotNull(e.getOriginalException()); +    isInstanceOf(CredentialsNotAvailableException.class, e.getOriginalException()); +    assertEquals("internal.pvp.01",          ((CredentialsNotAvailableException) e.getOriginalException()).getErrorId()); -    }    @Test @@ -198,33 +193,33 @@ public class GenerateMobilePhoneSignatureRequestTaskTest {    }    private void validate() throws Exception { -    Assert.assertEquals("HTTP Statuscode", 200, httpResp.getStatus()); -    Assert.assertEquals("ContentType", "text/html;charset=UTF-8", httpResp.getContentType()); -    Assert.assertEquals("ContentEncoding", "UTF-8", httpResp.getCharacterEncoding()); +    assertEquals("HTTP Statuscode", 200, httpResp.getStatus()); +    assertEquals("ContentType", "text/html;charset=UTF-8", httpResp.getContentType()); +    assertEquals("ContentEncoding", "UTF-8", httpResp.getCharacterEncoding());      final String html = httpResp.getContentAsString(); -    Assert.assertNotNull("XML Metadata", html); +    assertNotNull("XML Metadata", html);      final int startIndex = html.indexOf("SAMLRequest="); -    Assert.assertTrue("No SAMLRequest in html", startIndex >= 0); +    assertTrue("No SAMLRequest in html", startIndex >= 0);      final String authnXml = html.substring(startIndex + "SAMLRequest=".length());      // check if relaystate was stored      final int startIndexRelayState = html.indexOf("RelayState="); -    Assert.assertTrue("wrong RelayState in HTML", +    assertTrue("wrong RelayState in HTML",          startIndexRelayState >= 0);      final String relayState = html.substring(startIndexRelayState + "RelayState=".length(), startIndex);      final String storedPendingReqId = transactionStorage.get(relayState, String.class); -    Assert.assertEquals("relayStore not map to pendingRequestId", +    assertEquals("relayStore not map to pendingRequestId",          pendingReq.getPendingRequestId(), storedPendingReqId);      final AuthnRequest authnRequest = (AuthnRequest) XMLObjectSupport.unmarshallFromInputStream(          XMLObjectProviderRegistrySupport.getParserPool(), new ByteArrayInputStream(              Base64.getDecoder().decode(authnXml))); -    Assert.assertNotNull("AuthnReq", authnRequest); -    Assert.assertNotNull("Issuer", authnRequest.getIssuer()); -    Assert.assertEquals("EntityId", +    assertNotNull("AuthnReq", authnRequest); +    assertNotNull("Issuer", authnRequest.getIssuer()); +    assertEquals("EntityId",          "https://localhost/authhandler" + IdAustriaClientAuthConstants.ENDPOINT_METADATA,          authnRequest.getIssuer().getValue()); @@ -240,12 +235,11 @@ public class GenerateMobilePhoneSignatureRequestTaskTest {          metadataFactory.createMetadataProvider(METADATA_SP_PATH, null, "jUnit SP", null));      samlVerifyEngine.verify(msg, TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider)); -    Assert.assertNotNull("RequestedAuthnContext", authnRequest.getRequestedAuthnContext()); -    Assert.assertNotNull("AuthnContextClassRef", -        authnRequest.getRequestedAuthnContext().getAuthnContextClassRefs()); -    Assert.assertEquals("#AuthnContextClassRef", 1, +    assertNotNull("RequestedAuthnContext", authnRequest.getRequestedAuthnContext()); +    assertNotNull("AuthnContextClassRef", authnRequest.getRequestedAuthnContext().getAuthnContextClassRefs()); +    assertEquals("#AuthnContextClassRef", 1,          authnRequest.getRequestedAuthnContext().getAuthnContextClassRefs().size()); -    Assert.assertEquals("LoA", "http://eidas.europa.eu/LoA/high", +    assertEquals("LoA", "http://eidas.europa.eu/LoA/high",          authnRequest.getRequestedAuthnContext().getAuthnContextClassRefs().get(0).getAuthnContextClassRef());    } diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest.java index fb34a2dd..42dd3ddc 100644 --- a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest.java +++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest.java @@ -1,35 +1,5 @@  package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.tasks; -import static org.junit.Assert.assertThrows; - -import java.io.IOException; -import java.util.Base64; - -import javax.xml.transform.TransformerException; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.RandomStringUtils; -import org.joda.time.DateTime; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport; -import org.opensaml.core.xml.io.MarshallingException; -import org.opensaml.core.xml.io.UnmarshallingException; -import org.opensaml.core.xml.util.XMLObjectSupport; -import org.opensaml.saml.saml2.core.Issuer; -import org.opensaml.saml.saml2.core.Response; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; -  import at.asitplus.eidas.specific.connector.test.config.dummy.MsConnectorDummyConfigMap;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;  import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; @@ -57,6 +27,39 @@ import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.initialize.EaafOpenSaml3xIniti  import at.gv.egiz.eaaf.modules.pvp2.impl.utils.Saml2Utils;  import at.gv.egiz.eaaf.modules.pvp2.sp.exception.AuthnResponseValidationException;  import net.shibboleth.utilities.java.support.xml.XMLParserException; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.RandomStringUtils; +import org.joda.time.DateTime; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport; +import org.opensaml.core.xml.io.MarshallingException; +import org.opensaml.core.xml.io.UnmarshallingException; +import org.opensaml.core.xml.util.XMLObjectSupport; +import org.opensaml.saml.saml2.core.Issuer; +import org.opensaml.saml.saml2.core.Response; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.xml.transform.TransformerException; +import java.io.IOException; +import java.util.Base64; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.springframework.util.Assert.isInstanceOf;  @RunWith(SpringJUnit4ClassRunner.class)  @ContextConfiguration(locations = { @@ -67,9 +70,9 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {    private static final String METADATA_PATH = "classpath:/data/idp_metadata_classpath_entity.xml"; -  @Autowired(required = true) +  @Autowired    private ApplicationContext context; -  @Autowired(required = true) +  @Autowired    protected MsConnectorDummyConfigMap authConfig;    @Autowired    private IdAustriaClientAuthMetadataProvider metadataProvider; @@ -78,11 +81,10 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {    @Autowired    private PvpMetadataResolverFactory metadataFactory; -  final ExecutionContext executionContext = new ExecutionContextImpl(); +  private final ExecutionContext executionContext = new ExecutionContextImpl();    private MockHttpServletRequest httpReq;    private MockHttpServletResponse httpResp;    private DummyPendingRequest pendingReq; -  private DummyOA oaParam;    private ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask task; @@ -115,13 +117,11 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      RequestContextHolder.resetRequestAttributes();      RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpReq, httpResp)); -    authConfig.putConfigValue(IdAustriaClientAuthConstants.CONFIG_PROPS_ID_AUSTRIA_ENTITYID, -        METADATA_PATH); +    authConfig.putConfigValue(IdAustriaClientAuthConstants.CONFIG_PROPS_ID_AUSTRIA_ENTITYID, METADATA_PATH); -    oaParam = new DummyOA(); +    DummyOA oaParam = new DummyOA();      oaParam.setUniqueAppId("http://test.com/test"); -    oaParam.setTargetIdentifier( -        EaafConstants.URN_PREFIX_CDID + RandomStringUtils.randomAlphabetic(2)); +    oaParam.setTargetIdentifier(EaafConstants.URN_PREFIX_CDID + RandomStringUtils.randomAlphabetic(2));      pendingReq = new DummyPendingRequest();      pendingReq.initialize(httpReq, authConfig); @@ -129,7 +129,6 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      pendingReq.setOnlineApplicationConfiguration(oaParam);      metadataProvider.fullyDestroy(); -    }    @Test @@ -141,14 +140,11 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      final TaskExecutionException e = assertThrows(TaskExecutionException.class,          () -> task.execute(pendingReq, executionContext)); -    Assert.assertNotNull(e.getPendingRequestID()); -    Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -    Assert.assertNotNull(e.getOriginalException()); -    org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class, -        e.getOriginalException()); -    Assert.assertEquals("sp.pvp2.03", -        ((AuthnResponseValidationException) e.getOriginalException()).getErrorId()); - +    assertNotNull(e.getPendingRequestID()); +    assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +    assertNotNull(e.getOriginalException()); +    isInstanceOf(AuthnResponseValidationException.class, e.getOriginalException()); +    assertEquals("sp.pvp2.03", ((AuthnResponseValidationException) e.getOriginalException()).getErrorId());    }    @Test @@ -160,13 +156,11 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      final TaskExecutionException e = assertThrows(TaskExecutionException.class,          () -> task.execute(pendingReq, executionContext)); -    Assert.assertNotNull(e.getPendingRequestID()); -    Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -    Assert.assertNotNull(e.getOriginalException()); -    org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class, -        e.getOriginalException()); -    Assert.assertEquals("sp.pvp2.12", -        ((AuthnResponseValidationException) e.getOriginalException()).getErrorId()); +    assertNotNull(e.getPendingRequestID()); +    assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +    assertNotNull(e.getOriginalException()); +    isInstanceOf(AuthnResponseValidationException.class, e.getOriginalException()); +    assertEquals("sp.pvp2.12", ((AuthnResponseValidationException) e.getOriginalException()).getErrorId());    } @@ -175,14 +169,11 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      final TaskExecutionException e = assertThrows(TaskExecutionException.class,          () -> task.execute(pendingReq, executionContext)); -    Assert.assertNotNull(e.getPendingRequestID()); -    Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -    Assert.assertNotNull(e.getOriginalException()); -    org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class, -        e.getOriginalException()); -    Assert.assertEquals("sp.pvp2.12", -        ((AuthnResponseValidationException) e.getOriginalException()).getErrorId()); - +    assertNotNull(e.getPendingRequestID()); +    assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +    assertNotNull(e.getOriginalException()); +    isInstanceOf(AuthnResponseValidationException.class, e.getOriginalException()); +    assertEquals("sp.pvp2.12", ((AuthnResponseValidationException) e.getOriginalException()).getErrorId());    }    @Test @@ -195,13 +186,11 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      final TaskExecutionException e = assertThrows(TaskExecutionException.class,          () -> task.execute(pendingReq, executionContext)); -    Assert.assertNotNull(e.getPendingRequestID()); -    Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -    Assert.assertNotNull(e.getOriginalException()); -    org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class, -        e.getOriginalException()); -    Assert.assertEquals("sp.pvp2.12", -        ((AuthnResponseValidationException) e.getOriginalException()).getErrorId()); +    assertNotNull(e.getPendingRequestID()); +    assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +    assertNotNull(e.getOriginalException()); +    isInstanceOf(AuthnResponseValidationException.class, e.getOriginalException()); +    assertEquals("sp.pvp2.12", ((AuthnResponseValidationException) e.getOriginalException()).getErrorId());    } @@ -221,13 +210,11 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      final TaskExecutionException e = assertThrows(TaskExecutionException.class,          () -> task.execute(pendingReq, executionContext)); -    Assert.assertNotNull(e.getPendingRequestID()); -    Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -    Assert.assertNotNull(e.getOriginalException()); -    org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class, -        e.getOriginalException()); -    Assert.assertEquals("sp.pvp2.12", -        ((AuthnResponseValidationException) e.getOriginalException()).getErrorId()); +    assertNotNull(e.getPendingRequestID()); +    assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +    assertNotNull(e.getOriginalException()); +    isInstanceOf(AuthnResponseValidationException.class, e.getOriginalException()); +    assertEquals("sp.pvp2.12", ((AuthnResponseValidationException) e.getOriginalException()).getErrorId());    } @@ -246,14 +233,11 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      final TaskExecutionException e = assertThrows(TaskExecutionException.class,          () -> task.execute(pendingReq, executionContext)); -    Assert.assertNotNull(e.getPendingRequestID()); -    Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -    Assert.assertNotNull(e.getOriginalException()); -    org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class, -        e.getOriginalException()); -    Assert.assertEquals("sp.pvp2.11", -        ((EaafException) e.getOriginalException()).getErrorId()); - +    assertNotNull(e.getPendingRequestID()); +    assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +    assertNotNull(e.getOriginalException()); +    isInstanceOf(AuthnResponseValidationException.class, e.getOriginalException()); +    assertEquals("sp.pvp2.11", ((EaafException) e.getOriginalException()).getErrorId());    }    @Test @@ -275,13 +259,11 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      final TaskExecutionException e = assertThrows(TaskExecutionException.class,          () -> task.execute(pendingReq, executionContext)); -    Assert.assertNotNull(e.getPendingRequestID()); -    Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -    Assert.assertNotNull(e.getOriginalException()); -    org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class, -        e.getOriginalException()); -    Assert.assertEquals("sp.pvp2.12", -        ((EaafException) e.getOriginalException()).getErrorId()); +    assertNotNull(e.getPendingRequestID()); +    assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +    assertNotNull(e.getOriginalException()); +    isInstanceOf(AuthnResponseValidationException.class, e.getOriginalException()); +    assertEquals("sp.pvp2.12", ((EaafException) e.getOriginalException()).getErrorId());    } @@ -292,7 +274,7 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      authConfig.putConfigValue(IdAustriaClientAuthConstants.CONFIG_PROPS_ID_AUSTRIA_ENTITYID,          "http://wrong.idp/" + RandomStringUtils.randomAlphabetic(5)); -     +      metadataProvider.addMetadataResolverIntoChain(metadataFactory.createMetadataProvider(          METADATA_PATH, null, "jUnit IDP", null)); @@ -308,13 +290,11 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      final TaskExecutionException e = assertThrows(TaskExecutionException.class,          () -> task.execute(pendingReq, executionContext)); -    Assert.assertNotNull(e.getPendingRequestID()); -    Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -    Assert.assertNotNull(e.getOriginalException()); -    org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class, -        e.getOriginalException()); -    Assert.assertEquals("sp.pvp2.08", -        ((EaafException) e.getOriginalException()).getErrorId()); +    assertNotNull(e.getPendingRequestID()); +    assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +    assertNotNull(e.getOriginalException()); +    isInstanceOf(AuthnResponseValidationException.class, e.getOriginalException()); +    assertEquals("sp.pvp2.08", ((EaafException) e.getOriginalException()).getErrorId());    } @@ -338,13 +318,11 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      final TaskExecutionException e = assertThrows(TaskExecutionException.class,          () -> task.execute(pendingReq, executionContext)); -    Assert.assertNotNull(e.getPendingRequestID()); -    Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -    Assert.assertNotNull(e.getOriginalException()); -    org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class, -        e.getOriginalException()); -    Assert.assertEquals("sp.pvp2.12", -        ((EaafException) e.getOriginalException()).getErrorId()); +    assertNotNull(e.getPendingRequestID()); +    assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +    assertNotNull(e.getOriginalException()); +    isInstanceOf(AuthnResponseValidationException.class, e.getOriginalException()); +    assertEquals("sp.pvp2.12", ((EaafException) e.getOriginalException()).getErrorId());    } @@ -368,13 +346,11 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      final TaskExecutionException e = assertThrows(TaskExecutionException.class,          () -> task.execute(pendingReq, executionContext)); -    Assert.assertNotNull(e.getPendingRequestID()); -    Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -    Assert.assertNotNull(e.getOriginalException()); -    org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class, -        e.getOriginalException()); -    Assert.assertEquals("sp.pvp2.05", -        ((EaafException) e.getOriginalException()).getErrorId()); +    assertNotNull(e.getPendingRequestID()); +    assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +    assertNotNull(e.getOriginalException()); +    isInstanceOf(AuthnResponseValidationException.class, e.getOriginalException()); +    assertEquals("sp.pvp2.05", ((EaafException) e.getOriginalException()).getErrorId());    } @@ -399,9 +375,9 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      task.execute(pendingReq, executionContext);      // validate state -    Assert.assertTrue("process not cancelled", executionContext.isProcessCancelled()); -    Assert.assertTrue("process not stopped by user", pendingReq.isAbortedByUser()); -    Assert.assertFalse("should not authenticated", pendingReq.isAuthenticated()); +    assertTrue("process not cancelled", executionContext.isProcessCancelled()); +    assertTrue("process not stopped by user", pendingReq.isAbortedByUser()); +    assertFalse("should not authenticated", pendingReq.isAuthenticated());    } @@ -424,17 +400,14 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      try {        task.execute(pendingReq, executionContext); -      Assert.fail("Invalid response not detected"); +      fail("Invalid response not detected");      } catch (final TaskExecutionException e) { -      Assert.assertNotNull(e.getPendingRequestID()); -      Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -      Assert.assertNotNull(e.getOriginalException()); -      org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class, -          e.getOriginalException()); -      Assert.assertEquals("sp.pvp2.05", -          ((EaafException) e.getOriginalException()).getErrorId()); - +      assertNotNull(e.getPendingRequestID()); +      assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +      assertNotNull(e.getOriginalException()); +      isInstanceOf(AuthnResponseValidationException.class, e.getOriginalException()); +      assertEquals("sp.pvp2.05", ((EaafException) e.getOriginalException()).getErrorId());      }    } @@ -457,16 +430,14 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      try {        task.execute(pendingReq, executionContext); -      Assert.fail("Invalid response not detected"); +      fail("Invalid response not detected");      } catch (final TaskExecutionException e) { -      Assert.assertNotNull(e.getPendingRequestID()); -      Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -      Assert.assertNotNull(e.getOriginalException()); -      org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class, -          e.getOriginalException()); -      Assert.assertEquals("sp.pvp2.05", -          ((EaafException) e.getOriginalException()).getErrorId()); +      assertNotNull(e.getPendingRequestID()); +      assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +      assertNotNull(e.getOriginalException()); +      isInstanceOf(AuthnResponseValidationException.class, e.getOriginalException()); +      assertEquals("sp.pvp2.05", ((EaafException) e.getOriginalException()).getErrorId());      }    } @@ -501,8 +472,8 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      // validate state      final AuthProcessDataWrapper session = pendingReq.getSessionData(AuthProcessDataWrapper.class); -    Assert.assertEquals("LoA", "http://eidas.europa.eu/LoA/low", session.getQaaLevel()); -    Assert.assertEquals("IssueInstant", "2014-03-05T06:39:51Z", session.getIssueInstantString()); +    assertEquals("LoA", "http://eidas.europa.eu/LoA/low", session.getQaaLevel()); +    assertEquals("IssueInstant", "2014-03-05T06:39:51Z", session.getIssueInstantString());      //TODO: @@ -536,15 +507,14 @@ public class ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTaskTest {      // perform task      try {        task.execute(pendingReq, executionContext); -      Assert.fail("Invalid response not detected"); +      fail("Invalid response not detected");      } catch (final TaskExecutionException e) { -      Assert.assertNotNull(e.getPendingRequestID()); -      Assert.assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); -      Assert.assertNotNull(e.getOriginalException()); -      org.springframework.util.Assert.isInstanceOf(AuthnResponseValidationException.class, -          e.getOriginalException()); -      Assert.assertTrue(e.getOriginalException().getCause() instanceof InvalidUserInputException); +      assertNotNull(e.getPendingRequestID()); +      assertEquals(pendingReq.getPendingRequestId(), e.getPendingRequestID()); +      assertNotNull(e.getOriginalException()); +      isInstanceOf(AuthnResponseValidationException.class, e.getOriginalException()); +      assertTrue(e.getOriginalException().getCause() instanceof InvalidUserInputException);      }    } | 
