From 4c91ab37d4b3d2daa7c50edcf2002ea4f6b7fbe9 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Tue, 7 Apr 2020 17:25:09 +0200 Subject: inject VDA sessionId from SL2.0 error-response into internal error holder --- .../sl20/exceptions/SL20VdaResponseException.java | 41 ++++++++++++++++ .../sl20/tasks/AbstractReceiveQualEidTask.java | 57 ++++++++++++++-------- .../modules/auth/sl20/utils/SL20Constants.java | 6 +-- 3 files changed, 80 insertions(+), 24 deletions(-) create mode 100644 eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20VdaResponseException.java (limited to 'eaaf_modules') diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20VdaResponseException.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20VdaResponseException.java new file mode 100644 index 00000000..47f309f6 --- /dev/null +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/exceptions/SL20VdaResponseException.java @@ -0,0 +1,41 @@ +package at.gv.egiz.eaaf.modules.auth.sl20.exceptions; + +import javax.annotation.Nullable; + +public class SL20VdaResponseException extends SL20Exception { + + private static final long serialVersionUID = 6834803380740916320L; + + private String vdaSessionId = null; + + public SL20VdaResponseException(String messageId, Object[] parameters) { + super(messageId, parameters); + + } + + public SL20VdaResponseException(String messageId, Object[] parameters, Throwable wrapped) { + super(messageId, parameters, wrapped); + + } + + /** + * Get a SessionId that was provided by VDA in SL2.0 error-response. + * + * @return SessionId for an additional VDA request, or null + * if no SessionId was provided. + */ + @Nullable + public String getVdaSessionId() { + return vdaSessionId; + } + + /** + * Set SessionId from VDA that can be used for an further request to VDA for the same user. + * + * @param vdaSessionId SessionId provided by VDA + */ + public void setVdaSessionId(@Nullable String vdaSessionId) { + this.vdaSessionId = vdaSessionId; + } + +} diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualEidTask.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualEidTask.java index 655cc2c6..4786ff39 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualEidTask.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualEidTask.java @@ -6,6 +6,15 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.StringUtils; +import org.jose4j.base64url.Base64Url; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonNode; + import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; import at.gv.egiz.eaaf.core.exceptions.EaafAuthenticationException; import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; @@ -19,6 +28,7 @@ import at.gv.egiz.eaaf.modules.auth.sl20.EventCodes; import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult; import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception; import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20SecurityException; +import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20VdaResponseException; import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException; import at.gv.egiz.eaaf.modules.auth.sl20.utils.IJoseTools; import at.gv.egiz.eaaf.modules.auth.sl20.utils.JsonMapper; @@ -26,15 +36,6 @@ import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20Constants; import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20JsonExtractorUtils; import at.gv.egiz.eaaf.modules.auth.sl20.utils.SL20ResponseUtils; -import org.apache.commons.lang3.StringUtils; -import org.jose4j.base64url.Base64Url; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonNode; - public abstract class AbstractReceiveQualEidTask extends AbstractAuthServletTask { private static final Logger log = LoggerFactory.getLogger(AbstractReceiveQualEidTask.class); @@ -83,27 +84,41 @@ public abstract class AbstractReceiveQualEidTask extends AbstractAuthServletTask } catch (final JsonParseException e) { log.warn("SL2.0 command or result is NOT valid JSON.", e); log.debug("SL2.0 msg: " + sl20Result); - throw new SL20Exception("sl20.02", new Object[] { "SL2.0 command or result is NOT valid JSON." }, e); + throw new SL20Exception("sl20.02", new Object[] { "SL2.0 command or result is NOT valid JSON." }, + e); } // check on errorMessage - final VerificationResult payLoadContainerErrorCheck = SL20JsonExtractorUtils.extractSL20PayLoad(sl20ReqObj, + final VerificationResult payLoadContainerErrorCheck = SL20JsonExtractorUtils.extractSL20PayLoad( + sl20ReqObj, joseTools, false); if (SL20JsonExtractorUtils - .getStringValue(payLoadContainerErrorCheck.getPayload(), SL20Constants.SL20_COMMAND_CONTAINER_NAME, true) + .getStringValue(payLoadContainerErrorCheck.getPayload(), + SL20Constants.SL20_COMMAND_CONTAINER_NAME, true) .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR)) { log.debug("Find " + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR + " result .... "); - final JsonNode errorResult = SL20JsonExtractorUtils.extractSL20Result(payLoadContainerErrorCheck.getPayload(), + final JsonNode errorResult = SL20JsonExtractorUtils.extractSL20Result(payLoadContainerErrorCheck + .getPayload(), joseTools, false); final String errorCode = SL20JsonExtractorUtils.getStringValue(errorResult, SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE, true); final String errorMsg = SL20JsonExtractorUtils.getStringValue(errorResult, SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE, false); - log.info("Receiving errorcode: {} with msg: {} from VDA! Stopping auth-process ... ", errorCode, errorMsg); - // aTrustErrorWorkAround = true; - throw new SL20Exception("sl20.08", new Object[] { errorCode, errorMsg }); + final SL20VdaResponseException ex = new SL20VdaResponseException("sl20.08", new Object[] { + errorCode, errorMsg }); + log.info("Receiving errorcode: {} with msg: {} from VDA! Stopping auth-process ... ", errorCode, + errorMsg); + + final String vdaSessionId = SL20JsonExtractorUtils.getStringValue(errorResult, + SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERROR_VDASESSIONID, false); + if (StringUtils.isNotEmpty(vdaSessionId)) { + log.debug("VDA provides an optional sessionId. Inject it to internal error-holder "); + ex.setVdaSessionId(vdaSessionId); + + } + throw ex; } else { // Receive no error - To request validation @@ -111,7 +126,8 @@ public abstract class AbstractReceiveQualEidTask extends AbstractAuthServletTask // validate reqId with inResponseTo final String sl20ReqId = pendingReq .getRawData(Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_REQID, String.class); - final String inRespTo = SL20JsonExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_INRESPTO, true); + final String inRespTo = SL20JsonExtractorUtils.getStringValue(sl20ReqObj, + SL20Constants.SL20_INRESPTO, true); if (sl20ReqId == null || !sl20ReqId.equals(inRespTo)) { log.info("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); throw new SL20SecurityException( @@ -119,11 +135,13 @@ public abstract class AbstractReceiveQualEidTask extends AbstractAuthServletTask } // validate signature - final VerificationResult payLoadContainer = SL20JsonExtractorUtils.extractSL20PayLoad(sl20ReqObj, joseTools, + final VerificationResult payLoadContainer = SL20JsonExtractorUtils.extractSL20PayLoad(sl20ReqObj, + joseTools, authConfig.getBasicConfigurationBoolean(Constants.CONFIG_PROP_FORCE_EID_SIGNED_RESULT, true)); if (payLoadContainer.isValidSigned() == null || !payLoadContainer.isValidSigned()) { - if (authConfig.getBasicConfigurationBoolean(Constants.CONFIG_PROP_FORCE_EID_SIGNED_RESULT, true)) { + if (authConfig.getBasicConfigurationBoolean(Constants.CONFIG_PROP_FORCE_EID_SIGNED_RESULT, + true)) { log.info("SL20 result from VDA was not valid signed"); throw new SL20SecurityException(new Object[] { "Signature on SL20 result NOT valid." }); @@ -207,5 +225,4 @@ public abstract class AbstractReceiveQualEidTask extends AbstractAuthServletTask protected abstract String getResumeEndPoint(); - } diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20Constants.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20Constants.java index bfc393db..8c520931 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20Constants.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/SL20Constants.java @@ -58,7 +58,7 @@ public class SL20Constants { public String toString() { return getAuthMethod(); - } + } } public static final String PARAM_SL20_REQ_ICP_RETURN_URL_PARAM = "slIPCReturnUrl"; @@ -176,6 +176,7 @@ public class SL20Constants { // error command public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE = "errorCode"; public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE = "errorMessage"; + public static final String SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERROR_VDASESSIONID = "handySignaturSession"; // qualified eID command @Deprecated @@ -303,7 +304,4 @@ public class SL20Constants { // QR-Code authentication public static final String SL20_COMMAND_PARAM_AUTH_QRCODE_QRCODE = "qrCode"; public static final String SL20_COMMAND_PARAM_AUTH_QRCODE_DATAURL = SL20_COMMAND_PARAM_GENERAL_DATAURL; - - - } -- cgit v1.2.3