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 | |
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')
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); } } |