From 514747e925abddcb320a8433908dbae32dc5049b Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Fri, 28 Jun 2019 09:25:09 +0200 Subject: some small updates --- .../sl20/tasks/AbstractReceiveQualeIDTask.java | 197 ++++++++++++--------- 1 file changed, 118 insertions(+), 79 deletions(-) (limited to 'eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/tasks/AbstractReceiveQualeIDTask.java') 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 5abbd543..761c8b24 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 @@ -2,6 +2,7 @@ package at.gv.egiz.eaaf.modules.auth.sl20.tasks; import java.io.IOException; import java.io.StringWriter; +import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -10,6 +11,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.utils.URIBuilder; import org.apache.http.entity.ContentType; import org.jose4j.base64url.Base64Url; import org.slf4j.Logger; @@ -54,7 +56,12 @@ public abstract class AbstractReceiveQualeIDTask extends AbstractAuthServletTask try { log.debug("Receiving SL2.0 response process .... "); - JsonNode sl20ReqObj = null; + JsonNode sl20ReqObj = null; + + //A-Trust does not SET http-header 'SL2ClientType' with value 'native' + //If A-trust sends an error, its maybe FrontChannel on DataURL + boolean aTrustErrorWorkAround = false; + try { //get SL2.0 command or result from HTTP request final Map reqParams = getParameters(request); @@ -88,41 +95,61 @@ 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); - if (sl20ReqId == null || !sl20ReqId.equals(inRespTo)) { - log.info("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); - throw new SL20SecurityException("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); - } - - - //validate signature - final VerificationResult payLoadContainer = SL20JSONExtractorUtils.extractSL20PayLoad( - sl20ReqObj, joseTools, - authConfig.getBasicConfigurationBoolean(Constants.CONFIG_PROP_FORCE_EID_SIGNED_RESULT, true)); + //check on errorMessage + final VerificationResult payLoadContainerErrorCheck = SL20JSONExtractorUtils.extractSL20PayLoad(sl20ReqObj, joseTools, false); + if (SL20JSONExtractorUtils.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(), 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 ... "); + aTrustErrorWorkAround = true; + throw new SL20Exception("sl20.08", new Object[] {errorCode, errorMsg}); + + } else { + //Receive no error - To request validation + + //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); + if (sl20ReqId == null || !sl20ReqId.equals(inRespTo)) { + log.info("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); + throw new SL20SecurityException("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo); + } - if ( (payLoadContainer.isValidSigned() == null || !payLoadContainer.isValidSigned())) { - 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."}); - } else { - log.warn("SL20 result from VDA is NOT valid signed, but signatures-verification is DISABLED by configuration!"); - + //validate signature + 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)) { + log.info("SL20 result from VDA was not valid signed"); + throw new SL20SecurityException(new Object[]{"Signature on SL20 result NOT valid."}); + + } else { + log.warn("SL20 result from VDA is NOT valid signed, but signatures-verification is DISABLED by configuration!"); + + } } - } + + payLoadContainer.getCertChain(); - payLoadContainer.getCertChain(); - - - //extract payloaf - final JsonNode payLoad = payLoadContainer.getPayload(); - - //handle SL2.0 response payLoad - handleResponsePayLoad(payLoad); - + //extract payloaf + final JsonNode payLoad = payLoadContainer.getPayload(); + + + //handle SL2.0 response payLoad + handleResponsePayLoad(payLoad); + + } } catch (final EAAFAuthenticationException e) { log.warn("SL2.0 processing error:", e); @@ -147,7 +174,7 @@ public abstract class AbstractReceiveQualeIDTask extends AbstractAuthServletTask //write SL2.0 response if (sl20ReqObj != null) - buildResponse(request, response, sl20ReqObj); + buildResponse(request, response, sl20ReqObj, aTrustErrorWorkAround); else buildErrorResponse(request, response, "2000", "General transport Binding error"); @@ -197,59 +224,71 @@ public abstract class AbstractReceiveQualeIDTask extends AbstractAuthServletTask } - private void buildResponse(HttpServletRequest request, HttpServletResponse response, JsonNode sl20ReqObj) throws IOException, SL20Exception { - //create response - final Map reqParameters = new HashMap(); - reqParameters.put(EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID, pendingReq.getPendingRequestId()); - final ObjectNode callReqParams = SL20JSONBuilderUtils.createCallCommandParameters( - new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), getResumeEndPoint(), null), - SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_GET, - false, - reqParameters); - final ObjectNode callCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_CALL, callReqParams); + private void buildResponse(HttpServletRequest request, HttpServletResponse response, JsonNode sl20ReqObj, boolean aTrustErrorWorkAround) throws IOException, SL20Exception, URISyntaxException { + //create response + final Map reqParameters = new HashMap(); + reqParameters.put(EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID, pendingReq.getPendingRequestId()); + final ObjectNode callReqParams = SL20JSONBuilderUtils.createCallCommandParameters( + new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), getResumeEndPoint(), null), + SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_GET, + false, + reqParameters); + final ObjectNode callCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_CALL, callReqParams); - //build first redirect command for app - final ObjectNode redirectOneParams = SL20JSONBuilderUtils.createRedirectCommandParameters( - generateICPRedirectURLForDebugging(), - callCommand, null, true); - final ObjectNode redirectOneCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectOneParams); - - //build second redirect command for IDP - final ObjectNode redirectTwoParams = SL20JSONBuilderUtils.createRedirectCommandParameters( - new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), getResumeEndPoint(), pendingReq.getPendingRequestId()), - redirectOneCommand, null, true); - final ObjectNode redirectTwoCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectTwoParams); - - //build generic SL2.0 response container - final String transactionId = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_TRANSACTIONID, false); - final ObjectNode respContainer = SL20JSONBuilderUtils.createGenericRequest( - UUID.randomUUID().toString(), - transactionId, - redirectTwoCommand, - null); + //build first redirect command for app + final ObjectNode redirectOneParams = SL20JSONBuilderUtils.createRedirectCommandParameters( + generateICPRedirectURLForDebugging(), + callCommand, null, true); + final ObjectNode redirectOneCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectOneParams); + + //build second redirect command for IDP + final ObjectNode redirectTwoParams = SL20JSONBuilderUtils.createRedirectCommandParameters( + new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), getResumeEndPoint(), pendingReq.getPendingRequestId()), + redirectOneCommand, null, true); + final ObjectNode redirectTwoCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectTwoParams); + + //build generic SL2.0 response container + final String transactionId = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_TRANSACTIONID, false); + final ObjectNode respContainer = SL20JSONBuilderUtils.createGenericRequest( + UUID.randomUUID().toString(), + transactionId, + redirectTwoCommand, + null); //workaround for A-Trust - if (request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null && + if (request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null && request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE).equals(SL20Constants.HTTP_HEADER_VALUE_NATIVE) - || true) { + || !aTrustErrorWorkAround) { log.debug("Client request containts 'native client' header ... "); log.trace("SL20 response to VDA: " + respContainer); - final StringWriter writer = new StringWriter(); - writer.write(respContainer.toString()); - final byte[] content = writer.toString().getBytes("UTF-8"); - response.setStatus(HttpServletResponse.SC_OK); - response.setContentLength(content.length); - response.setContentType(ContentType.APPLICATION_JSON.toString()); - response.getOutputStream().write(content); - - - } else { - log.info("SL2.0 DataURL communication needs http header: '" + SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + "'"); - throw new SL20Exception("sl20.06", - new Object[] {"SL2.0 DataURL communication needs http header: '" + SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + "'"}); - - } - } + final StringWriter writer = new StringWriter(); + writer.write(respContainer.toString()); + final byte[] content = writer.toString().getBytes("UTF-8"); + response.setStatus(HttpServletResponse.SC_OK); + response.setContentLength(content.length); + response.setContentType(ContentType.APPLICATION_JSON.toString()); + response.getOutputStream().write(content); + + + } else { + log.info("SL2.0 DataURL communication needs http header: '" + SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + "'"); + + log.debug("Client request containts is no native client ... "); + final URIBuilder clientRedirectURI = new URIBuilder( + new DataURLBuilder().buildDataURL( + pendingReq.getAuthURL(), getResumeEndPoint(), pendingReq.getPendingRequestId())); + response.setStatus(Integer.parseInt( + authConfig.getBasicConfiguration( + Constants.CONFIG_PROP_HTTP_REDIRECT_CODE, + Constants.CONFIG_PROP_HTTP_REDIRECT_CODE_DEFAULT_VALUE))); + response.setHeader("Location", clientRedirectURI.build().toString()); + + +// throw new SL20Exception("sl20.06", +// new Object[] {"SL2.0 DataURL communication needs http header: '" + SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE + "'"}); + + } + } /** * Generates a IPC redirect URL that is configured on IDP side -- cgit v1.2.3