aboutsummaryrefslogtreecommitdiff
path: root/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules
diff options
context:
space:
mode:
authorChristian Kollmann <christian.kollmann@a-sit.at>2021-02-22 15:46:10 +0100
committerChristian Kollmann <christian.kollmann@a-sit.at>2021-02-22 15:46:10 +0100
commit3338a3dd00fabf28f1de8579535b1626dbe99908 (patch)
tree82065cd76ba01552c80fc178a9c39a33d69bb850 /eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules
parent87e5fa9dd9966d427e45e36b9c3530b3c28d1f32 (diff)
downloadNational_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/main/java/at/asitplus/eidas/specific/modules')
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/GenerateMobilePhoneSignatureRequestTask.java124
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseAndSearchInRegistersTask.java307
2 files changed, 203 insertions, 228 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;
}