aboutsummaryrefslogtreecommitdiff
path: root/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/ReceiveQualeIDTask.java
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/ReceiveQualeIDTask.java')
-rw-r--r--id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/ReceiveQualeIDTask.java327
1 files changed, 178 insertions, 149 deletions
diff --git a/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/ReceiveQualeIDTask.java b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/ReceiveQualeIDTask.java
index 90e19326e..b7fe579a3 100644
--- a/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/ReceiveQualeIDTask.java
+++ b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/ReceiveQualeIDTask.java
@@ -1,9 +1,8 @@
package at.gv.egovernment.moa.id.auth.modules.sl20_auth.tasks;
-import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.StringWriter;
import java.security.cert.X509Certificate;
-import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -13,7 +12,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.entity.ContentType;
-import org.jose4j.keys.X509Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -35,18 +33,12 @@ import at.gv.egovernment.moa.id.auth.modules.sl20_auth.sl20.IJOSETools;
import at.gv.egovernment.moa.id.auth.modules.sl20_auth.sl20.SL20Constants;
import at.gv.egovernment.moa.id.auth.modules.sl20_auth.sl20.SL20JSONBuilderUtils;
import at.gv.egovernment.moa.id.auth.modules.sl20_auth.sl20.SL20JSONExtractorUtils;
-import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser;
import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants;
-import at.gv.egovernment.moa.id.commons.api.data.IIdentityLink;
import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException;
import at.gv.egovernment.moa.id.process.api.ExecutionContext;
-import at.gv.egovernment.moa.id.protocols.AbstractAuthProtocolModulController;
-import at.gv.egovernment.moa.util.Base64Utils;
-import at.gv.egovernment.moa.util.DateTimeUtils;
import at.gv.egovernment.moa.util.MiscUtil;
import at.gv.egovernment.moaspss.logging.Logger;
-import iaik.esi.sva.util.X509Utils;
-import iaik.utils.Util;
+
@Component("ReceiveQualeIDTask")
public class ReceiveQualeIDTask extends AbstractAuthServletTask {
@@ -57,173 +49,210 @@ public class ReceiveQualeIDTask extends AbstractAuthServletTask {
public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
throws TaskExecutionException {
- Logger.debug("Receiving SL2.0 response process .... ");
try {
- //get SL2.0 command or result from HTTP request
- Map<String, String> reqParams = getParameters(request);
- String sl20Result = reqParams.get(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM);
- if (MiscUtil.isEmpty(sl20Result)) {
- Logger.info("NO SL2.0 commando or result FOUND.");
- throw new SL20Exception("sl20.04", null);
-
- }
-
-
- //parse SL2.0 command/result into JSON
+ Logger.debug("Receiving SL2.0 response process .... ");
JsonObject sl20ReqObj = null;
try {
- JsonParser jsonParser = new JsonParser();
- JsonElement sl20Req = jsonParser.parse(sl20Result);
- sl20ReqObj = sl20Req.getAsJsonObject();
+ //get SL2.0 command or result from HTTP request
+ Map<String, String> reqParams = getParameters(request);
+ String sl20Result = reqParams.get(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM);
+ if (MiscUtil.isEmpty(sl20Result)) {
+ Logger.info("NO SL2.0 commando or result FOUND.");
+ throw new SL20Exception("sl20.04", null);
+
+ }
+
+ //parse SL2.0 command/result into JSON
+ try {
+ JsonParser jsonParser = new JsonParser();
+ JsonElement sl20Req = jsonParser.parse(sl20Result);
+ sl20ReqObj = sl20Req.getAsJsonObject();
+
+ } catch (JsonSyntaxException e) {
+ Logger.warn("SL2.0 command or result is NOT valid JSON.", e);
+ Logger.debug("SL2.0 msg: " + sl20Result);
+ throw new SL20Exception("sl20.02", new Object[]{"SL2.0 command or result is NOT valid JSON."}, e);
+
+ }
- } catch (JsonSyntaxException e) {
- Logger.warn("SL2.0 command or result is NOT valid JSON.", e);
- Logger.debug("SL2.0 msg: " + sl20Result);
- throw new SL20Exception("sl20.02", new Object[]{"SL2.0 command or result is NOT valid JSON."}, e);
+ //validate reqId with inResponseTo
+ String sl20ReqId = pendingReq.getGenericData(Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_REQID, String.class);
+ String inRespTo = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_INRESPTO, true);
+ if (sl20ReqId == null || !sl20ReqId.equals(inRespTo)) {
+ Logger.info("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo);
+ throw new SL20SecurityException("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo);
+ }
- }
-
- //validate reqId with inResponseTo
- String sl20ReqId = pendingReq.getGenericData(Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_REQID, String.class);
- String inRespTo = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_INRESPTO, true);
- if (sl20ReqId == null || !sl20ReqId.equals(inRespTo)) {
- Logger.info("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo);
- throw new SL20SecurityException("SL20 'reqId': " + sl20ReqId + " does NOT match to 'inResponseTo':" + inRespTo);
- }
-
-
- //validate signature
- VerificationResult payLoadContainer = SL20JSONExtractorUtils.extractSL20PayLoad(sl20ReqObj, joseTools, true);
- if (payLoadContainer.isValidSigned() == null ||
- !payLoadContainer.isValidSigned()) {
- Logger.info("SL20 result from VDA was not valid signed");
- throw new SL20SecurityException(new Object[]{"Signature on SL20 result NOT valid."});
- }
-
- //TODO validate certificate
- List<X509Certificate> sigCertChain = payLoadContainer.getCertChain();
-
-
- //extract payloaf
- JsonObject payLoad = payLoadContainer.getPayload();
-
- //check response type
- if (SL20JSONExtractorUtils.getStringValue(
- payLoad, SL20Constants.SL20_COMMAND_CONTAINER_NAME, true)
- .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_QUALIFIEDEID)) {
- Logger.debug("Find " + SL20Constants.SL20_COMMAND_IDENTIFIER_QUALIFIEDEID + " result .... ");
-
- //TODO: activate decryption in 'SL20JSONExtractorUtils.extractSL20Result'
- JsonElement qualeIDResult = SL20JSONExtractorUtils.extractSL20Result(payLoad, joseTools, false);
-
- //extract attributes from result
- String idlB64 = SL20JSONExtractorUtils.getStringValue(qualeIDResult.getAsJsonObject(),
- SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_IDL, true);
- String authBlockB64 = SL20JSONExtractorUtils.getStringValue(qualeIDResult.getAsJsonObject(),
- SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_AUTHBLOCK, true);
- String ccsURL = SL20JSONExtractorUtils.getStringValue(qualeIDResult.getAsJsonObject(),
- SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_CCSURL, true);
- String LoA = SL20JSONExtractorUtils.getStringValue(qualeIDResult.getAsJsonObject(),
- SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_LOA, true);
+ //validate signature
+ VerificationResult payLoadContainer = SL20JSONExtractorUtils.extractSL20PayLoad(sl20ReqObj, joseTools, true);
+ if (payLoadContainer.isValidSigned() == null ||
+ !payLoadContainer.isValidSigned()) {
+ Logger.info("SL20 result from VDA was not valid signed");
+ throw new SL20SecurityException(new Object[]{"Signature on SL20 result NOT valid."});
+
+ }
+ /*TODO validate certificate by using MOA-SPSS
+ * currently, the certificate is validated in IJOSETools by using a pkcs12 or jks keystore
+ */
+ List<X509Certificate> sigCertChain = payLoadContainer.getCertChain();
- //TODO: validate results
- IIdentityLink idl = new IdentityLinkAssertionParser(new ByteArrayInputStream(Base64Utils.decode(idlB64, false))).parseIdentityLink();
+ //extract payloaf
+ JsonObject payLoad = payLoadContainer.getPayload();
+ //check response type
+ if (SL20JSONExtractorUtils.getStringValue(
+ payLoad, SL20Constants.SL20_COMMAND_CONTAINER_NAME, true)
+ .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_QUALIFIEDEID)) {
+ Logger.debug("Find " + SL20Constants.SL20_COMMAND_IDENTIFIER_QUALIFIEDEID + " result .... ");
+
+ JsonElement qualeIDResult = SL20JSONExtractorUtils.extractSL20Result(
+ payLoad, joseTools,
+ authConfig.getBasicMOAIDConfigurationBoolean(Constants.CONFIG_PROP_DISABLE_EID_ENCRYPTION, true));
+
+ //extract attributes from result
+ String idlB64 = SL20JSONExtractorUtils.getStringValue(qualeIDResult.getAsJsonObject(),
+ SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_IDL, true);
+ String authBlockB64 = SL20JSONExtractorUtils.getStringValue(qualeIDResult.getAsJsonObject(),
+ SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_AUTHBLOCK, true);
+ String ccsURL = SL20JSONExtractorUtils.getStringValue(qualeIDResult.getAsJsonObject(),
+ SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_CCSURL, true);
+ String LoA = SL20JSONExtractorUtils.getStringValue(qualeIDResult.getAsJsonObject(),
+ SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_LOA, true);
+
+ //cache qualified eID data into pending request
+ pendingReq.setGenericDataToSession(
+ Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_IDL,
+ idlB64);
+ pendingReq.setGenericDataToSession(
+ Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_AUTHBLOCK,
+ authBlockB64);
+ pendingReq.setGenericDataToSession(
+ Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_CCSURL,
+ ccsURL);
+ pendingReq.setGenericDataToSession(
+ Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_LOA,
+ LoA);
+
+ } else {
+ Logger.info("SL20 response is NOT a " + SL20Constants.SL20_COMMAND_IDENTIFIER_QUALIFIEDEID + " result");
+ throw new SLCommandoParserException("SL20 response is NOT a " + SL20Constants.SL20_COMMAND_IDENTIFIER_QUALIFIEDEID + " result");
+ }
- //add into session
- defaultTaskInitialization(request, executionContext);
- moasession.setIdentityLink(idl);
- moasession.setBkuURL(ccsURL);
- //TODO: from AuthBlock
- moasession.setIssueInstant(DateTimeUtils.buildDateTimeUTC(Calendar.getInstance()));
- moasession.setQAALevel(LoA);
- //mark as authenticated
- moasession.setAuthenticated(true);
- pendingReq.setAuthenticated(true);
-
- //store pending request
- requestStoreage.storePendingRequest(pendingReq);
-
- //create response
- Map<String, String> reqParameters = new HashMap<String, String>();
- reqParameters.put(MOAIDAuthConstants.PARAM_TARGET_PENDINGREQUESTID, pendingReq.getRequestID());
- JsonObject callReqParams = SL20JSONBuilderUtils.createCallCommandParameters(
- new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), AbstractAuthProtocolModulController.FINALIZEPROTOCOL_ENDPOINT, null),
- SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_GET,
- false,
- reqParameters);
- JsonObject callCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_CALL, callReqParams);
+ } catch (MOAIDException e) {
+ Logger.warn("SL2.0 processing error:", e);
+ pendingReq.setGenericDataToSession(
+ Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR,
+ new TaskExecutionException(pendingReq, "SL2.0 Authentication FAILED. Msg: " + e.getMessage(), e));
- //build first redirect command for app
- JsonObject redirectOneParams = SL20JSONBuilderUtils.createRedirectCommandParameters("", callCommand, null, true);
- JsonObject redirectOneCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectOneParams);
-
- //build second redirect command for IDP
- JsonObject redirectTwoParams = SL20JSONBuilderUtils.createRedirectCommandParameters(
- new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), AbstractAuthProtocolModulController.FINALIZEPROTOCOL_ENDPOINT, null),
- redirectOneCommand, null, true);
- JsonObject redirectTwoCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectTwoParams);
+ } catch (Exception e) {
+ Logger.warn("ERROR:", e);
+ Logger.warn("SL2.0 Authentication FAILED with a generic error.", e);
+ pendingReq.setGenericDataToSession(
+ Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR,
+ new TaskExecutionException(pendingReq, e.getMessage(), e));
- //build generic SL2.0 response container
- String transactionId = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_TRANSACTIONID, false);
- JsonObject respContainer = SL20JSONBuilderUtils.createGenericRequest(
- UUID.randomUUID().toString(),
- transactionId,
- redirectTwoCommand,
- null);
+ } finally {
+ //store pending request
+ requestStoreage.storePendingRequest(pendingReq);
- if (request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE) != null &&
- request.getHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE).equals(SL20Constants.HTTP_HEADER_VALUE_NATIVE)) {
- Logger.debug("Client request containts 'native client' header ... ");
- 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);
+ //write SL2.0 response
+ if (sl20ReqObj != null)
+ buildResponse(request, response, sl20ReqObj);
+ else
+ buildErrorResponse(request, response, "2000", "General transport Binding error");
-
- } else {
- Logger.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 + "'"});
-
- }
-
- } else {
- Logger.info("SL20 response is NOT a " + SL20Constants.SL20_COMMAND_IDENTIFIER_QUALIFIEDEID + " result");
- throw new SLCommandoParserException("SL20 response is NOT a " + SL20Constants.SL20_COMMAND_IDENTIFIER_QUALIFIEDEID + " result");
}
-
-
- } catch (MOAIDException e) {
- Logger.warn("ERROR:", e);
- throw new TaskExecutionException(pendingReq, "SL2.0 Authentication FAILED. Msg: " + e.getMessage(), e);
-
+
} catch (Exception e) {
- Logger.warn("ERROR:", e);
- Logger.warn("SL2.0 Authentication FAILED with a generic error.", e);
- throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+ //write internal server errror 500 according to SL2.0 specification, chapter https transport binding
+ Logger.warn("Can NOT build SL2.0 response. Reason: " + e.getMessage(), e);
+ try {
+ response.sendError(500, "Internal Server Error.");
+
+ } catch (IOException e1) {
+ Logger.error("Can NOT send error message. SOMETHING IS REALY WRONG!", e);
+
+ }
- } finally {
+ } finally {
TransactionIDUtils.removeTransactionId();
TransactionIDUtils.removeSessionId();
}
}
-
- private JsonObject createRedirectCommand() {
-
+ private void buildErrorResponse(HttpServletRequest request, HttpServletResponse response, String errorCode, String errorMsg) throws Exception {
+ JsonObject error = SL20JSONBuilderUtils.createErrorCommandResult(errorCode, errorMsg);
+ JsonObject respContainer = SL20JSONBuilderUtils.createGenericRequest(
+ UUID.randomUUID().toString(),
+ null,
+ error ,
+ null);
+
+ Logger.debug("Client request containts 'native client' header ... ");
+ 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);
+
+ }
+
+ private void buildResponse(HttpServletRequest request, HttpServletResponse response, JsonObject sl20ReqObj) throws IOException, SL20Exception {
+ //create response
+ Map<String, String> reqParameters = new HashMap<String, String>();
+ reqParameters.put(MOAIDAuthConstants.PARAM_TARGET_PENDINGREQUESTID, pendingReq.getRequestID());
+ JsonObject callReqParams = SL20JSONBuilderUtils.createCallCommandParameters(
+ new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), Constants.HTTP_ENDPOINT_RESUME, null),
+ SL20Constants.SL20_COMMAND_PARAM_GENERAL_CALL_METHOD_GET,
+ false,
+ reqParameters);
+ JsonObject callCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_CALL, callReqParams);
- return null;
+ //build first redirect command for app
+ JsonObject redirectOneParams = SL20JSONBuilderUtils.createRedirectCommandParameters("", callCommand, null, true);
+ JsonObject redirectOneCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectOneParams);
+
+ //build second redirect command for IDP
+ JsonObject redirectTwoParams = SL20JSONBuilderUtils.createRedirectCommandParameters(
+ new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), Constants.HTTP_ENDPOINT_RESUME, null),
+ redirectOneCommand, null, true);
+ JsonObject redirectTwoCommand = SL20JSONBuilderUtils.createCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT, redirectTwoParams);
+ //build generic SL2.0 response container
+ String transactionId = SL20JSONExtractorUtils.getStringValue(sl20ReqObj, SL20Constants.SL20_TRANSACTIONID, false);
+ JsonObject respContainer = SL20JSONBuilderUtils.createGenericRequest(
+ UUID.randomUUID().toString(),
+ transactionId,
+ redirectTwoCommand,
+ 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)) {
+ Logger.debug("Client request containts 'native client' header ... ");
+ 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 {
+ Logger.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 + "'"});
+
+ }
}
+
+
}