aboutsummaryrefslogtreecommitdiff
path: root/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/CreateQualeIDRequestTask.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/CreateQualeIDRequestTask.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/CreateQualeIDRequestTask.java243
1 files changed, 243 insertions, 0 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/CreateQualeIDRequestTask.java b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/CreateQualeIDRequestTask.java
new file mode 100644
index 000000000..3408cf538
--- /dev/null
+++ b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/CreateQualeIDRequestTask.java
@@ -0,0 +1,243 @@
+package at.gv.egovernment.moa.id.auth.modules.sl20_auth.tasks;
+
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.net.ssl.SSLSocketFactory;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.jose4j.base64url.Base64Url;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.google.gson.JsonObject;
+
+import at.gv.egiz.eaaf.core.api.idp.ISPConfiguration;
+import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
+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.DataURLBuilder;
+import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils;
+import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.SAML2Utils;
+import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
+import at.gv.egovernment.moa.id.auth.modules.sl20_auth.Constants;
+import at.gv.egovernment.moa.id.auth.modules.sl20_auth.data.VerificationResult;
+import at.gv.egovernment.moa.id.auth.modules.sl20_auth.exceptions.SL20Exception;
+import at.gv.egovernment.moa.id.auth.modules.sl20_auth.exceptions.SLCommandoParserException;
+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.SL20HttpBindingUtils;
+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.commons.api.AuthConfiguration;
+import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException;
+import at.gv.egovernment.moa.id.commons.config.MOAIDConfigurationConstants;
+import at.gv.egovernment.moa.id.commons.utils.HttpClientWithProxySupport;
+import at.gv.egovernment.moa.id.util.SSLUtils;
+import at.gv.egovernment.moa.util.MiscUtil;
+import at.gv.egovernment.moaspss.logging.Logger;
+
+@Component("CreateQualeIDRequestTask")
+public class CreateQualeIDRequestTask extends AbstractAuthServletTask {
+
+ @Autowired(required=true) private IJOSETools joseTools;
+ @Autowired private AuthConfiguration moaAuthConfig;
+
+ @Override
+ public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
+ throws TaskExecutionException {
+
+ Logger.debug("Starting SL2.0 authentication process .... ");
+
+ revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.AUTHPROCESS_BKUTYPE_SELECTED, "sl20auth");
+
+ try {
+ //get service-provider configuration
+ ISPConfiguration oaConfig = pendingReq.getServiceProviderConfiguration();
+
+ //get basic configuration parameters
+ String vdaQualeIDUrl = extractVDAURLForSpecificOA(oaConfig, executionContext);
+ if (MiscUtil.isEmpty(vdaQualeIDUrl)) {
+ Logger.error("NO VDA URL for qualified eID (" + Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT + ")");
+ throw new SL20Exception("sl20.03", new Object[]{"NO VDA URL for qualified eID"});
+
+ }
+ revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.AUTHPROCESS_BKU_URL, vdaQualeIDUrl);
+
+
+ String authBlockId = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_VDA_AUTHBLOCK_ID);
+ if (MiscUtil.isEmpty(authBlockId)) {
+ Logger.error("NO AuthBlock Template identifier for qualified eID (" + Constants.CONFIG_PROP_VDA_AUTHBLOCK_ID + ")");
+ throw new SL20Exception("sl20.03", new Object[]{"NO AuthBlock Template identifier for qualified eID"});
+
+ }
+
+ //build DataURL for qualified eID response
+ String dataURL = new DataURLBuilder().buildDataURL(
+ pendingReq.getAuthURL(), Constants.HTTP_ENDPOINT_DATAURL, pendingReq.getPendingRequestId());
+
+ //build qualifiedeID command
+ Map<String, String> qualifiedeIDParams = new HashMap<String, String>();
+ qualifiedeIDParams.put(SL20Constants.SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPUNIQUEID, oaConfig.getUniqueIdentifier());
+ qualifiedeIDParams.put(SL20Constants.SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPFRIENDLYNAME, oaConfig.getFriendlyName());
+ qualifiedeIDParams.put(SL20Constants.SL20_COMMAND_PARAM_EID_ATTRIBUTES_SPCOUNTRYCODE, "AT");
+ //qualifiedeIDParams.put(SL20Constants.SL20_COMMAND_PARAM_EID_ATTRIBUTES_MANDATEREFVALUE, UUID.randomUUID().toString());
+
+
+ X509Certificate encCert = null;
+ if (authConfig.getBasicMOAIDConfigurationBoolean(Constants.CONFIG_PROP_ENABLE_EID_ENCRYPTION, true))
+ encCert = joseTools.getEncryptionCertificate();
+ else
+ Logger.info("eID data encryption is disabled by configuration");
+
+ JsonObject qualeIDCommandParams = SL20JSONBuilderUtils.createQualifiedeIDCommandParameters(
+ authBlockId,
+ dataURL,
+ qualifiedeIDParams,
+ encCert
+ );
+
+ //String qualeIDReqId = UUID.randomUUID().toString();
+ String qualeIDReqId = SAML2Utils.getSecureIdentifier();
+ String signedQualeIDCommand = SL20JSONBuilderUtils.createSignedCommand(SL20Constants.SL20_COMMAND_IDENTIFIER_QUALIFIEDEID, qualeIDCommandParams, joseTools);
+ JsonObject sl20Req = SL20JSONBuilderUtils.createGenericRequest(qualeIDReqId, null, null, signedQualeIDCommand);
+
+ //open http client
+ SSLSocketFactory sslFactory = SSLUtils.getSSLSocketFactory(
+ moaAuthConfig,
+ vdaQualeIDUrl);
+ CloseableHttpClient httpClient = HttpClientWithProxySupport.getHttpClient(
+ sslFactory,
+ moaAuthConfig.getBasicMOAIDConfigurationBoolean(AuthConfiguration.PROP_KEY_OVS_SSL_HOSTNAME_VALIDATION, true));
+
+ //build http POST request
+ HttpPost httpReq = new HttpPost(new URIBuilder(vdaQualeIDUrl).build());
+ List<NameValuePair> parameters = new ArrayList<NameValuePair>();;
+ parameters.add(new BasicNameValuePair(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM, Base64Url.encode(sl20Req.toString().getBytes())));
+ httpReq.setEntity(new UrlEncodedFormEntity(parameters ));
+
+ //build http GET request
+// URIBuilder sl20ReqUri = new URIBuilder(vdaQualeIDUrl);
+// sl20ReqUri.addParameter(SL20Constants.PARAM_SL20_REQ_COMMAND_PARAM, Base64Url.encode(sl20Req.toString().getBytes()));
+// HttpGet httpReq = new HttpGet(sl20ReqUri.build());
+
+ //set native client header
+ httpReq.addHeader(SL20Constants.HTTP_HEADER_SL20_CLIENT_TYPE, SL20Constants.HTTP_HEADER_VALUE_NATIVE);
+
+ Logger.trace("Request VDA via SL20 with: " + Base64Url.encode(sl20Req.toString().getBytes()));
+
+ //request VDA
+ HttpResponse httpResp = httpClient.execute(httpReq);
+
+ //parse response
+ Logger.info("Receive response from VDA ... ");
+ JsonObject sl20Resp = SL20JSONExtractorUtils.getSL20ContainerFromResponse(httpResp);
+ VerificationResult respPayloadContainer = SL20JSONExtractorUtils.extractSL20PayLoad(sl20Resp, null, false);
+
+ if (respPayloadContainer.isValidSigned() == null) {
+ Logger.debug("Receive unsigned payLoad from VDA");
+
+ }
+
+ JsonObject respPayload = respPayloadContainer.getPayload();
+ if (respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).getAsString()
+ .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_REDIRECT)) {
+ Logger.debug("Find 'redirect' command in VDA response ... ");
+ JsonObject params = SL20JSONExtractorUtils.getJSONObjectValue(respPayload, SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, true);
+ String redirectURL = SL20JSONExtractorUtils.getStringValue(params, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_URL, true);
+ JsonObject command = SL20JSONExtractorUtils.getJSONObjectValue(params, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_COMMAND, false);
+ String signedCommand = SL20JSONExtractorUtils.getStringValue(params, SL20Constants.SL20_COMMAND_PARAM_GENERAL_REDIRECT_SIGNEDCOMMAND, false);
+
+ //create forward SL2.0 command
+ JsonObject sl20Forward = sl20Resp.deepCopy().getAsJsonObject();
+ SL20JSONBuilderUtils.addOnlyOnceOfTwo(sl20Forward,
+ SL20Constants.SL20_PAYLOAD, SL20Constants.SL20_SIGNEDPAYLOAD,
+ command, signedCommand);
+
+ //store pending request
+ pendingReq.setRawDataToTransaction(Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_REQID,
+ qualeIDReqId);
+ requestStoreage.storePendingRequest(pendingReq);
+
+ //forward SL2.0 command
+ //TODO: maybe add SL2ClientType Header from execution context
+ SL20HttpBindingUtils.writeIntoResponse(request, response, sl20Forward, redirectURL);
+
+ } else if (respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).getAsString()
+ .equals(SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR)) {
+ JsonObject result = SL20JSONExtractorUtils.getJSONObjectValue(respPayload, SL20Constants.SL20_COMMAND_CONTAINER_RESULT, false);
+ if (result == null)
+ result = SL20JSONExtractorUtils.getJSONObjectValue(respPayload, SL20Constants.SL20_COMMAND_CONTAINER_PARAMS, false);
+
+ String errorCode = SL20JSONExtractorUtils.getStringValue(result, SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORCODE, true);
+ String errorMsg = SL20JSONExtractorUtils.getStringValue(result, SL20Constants.SL20_COMMAND_PARAM_GENERAL_RESPONSE_ERRORMESSAGE, true);
+
+ Logger.info("Receive SL2.0 error. Code:" + errorCode + " Msg:" + errorMsg);
+ throw new SL20Exception("sl20.08", new Object[]{errorCode, errorMsg});
+
+ } else {
+ //TODO: update to add error handling
+ Logger.warn("Received an unrecognized command: " + respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).getAsString());
+ throw new SLCommandoParserException("Received an unrecognized command: \" + respPayload.get(SL20Constants.SL20_COMMAND_CONTAINER_NAME).getAsString()");
+ }
+
+
+ } catch (MOAIDException e) {
+ throw new TaskExecutionException(pendingReq, "SL2.0 Authentication FAILED. Msg: " + e.getMessage(), e);
+
+ } catch (Exception e) {
+ Logger.warn("SL2.0 Authentication FAILED with a generic error.", e);
+ throw new TaskExecutionException(pendingReq, e.getMessage(), e);
+
+ } finally {
+ TransactionIDUtils.removeTransactionId();
+ TransactionIDUtils.removeSessionId();
+
+ }
+
+ }
+
+ private String extractVDAURLForSpecificOA(ISPConfiguration oaConfig, ExecutionContext executionContext) {
+ String spSpecificVDAEndpoints = oaConfig.getConfigurationValue(MOAIDConfigurationConstants.SERVICE_AUTH_SL20_ENDPOINTS);
+ Map<String, String> endPointMap = authConfig.getBasicMOAIDConfigurationWithPrefix(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_LIST);
+ if (MiscUtil.isNotEmpty(spSpecificVDAEndpoints)) {
+ endPointMap.putAll(KeyValueUtils.convertListToMap(
+ KeyValueUtils.getListOfCSVValues(
+ KeyValueUtils.normalizeCSVValueString(spSpecificVDAEndpoints))));
+ Logger.debug("Find OA specific SL2.0 endpoints. Updating endPoint list ... ");
+
+ }
+
+ Logger.trace("Find #" + endPointMap.size() + " SL2.0 endpoints ... ");
+
+ //selection based on request Header
+ String sl20VDATypeHeader = (String) executionContext.get(SL20Constants.HTTP_HEADER_SL20_VDA_TYPE.toLowerCase());
+ if (MiscUtil.isNotEmpty(sl20VDATypeHeader)) {
+ String vdaURL = endPointMap.get(sl20VDATypeHeader);
+ if (MiscUtil.isNotEmpty(vdaURL))
+ return vdaURL.trim();
+
+ else
+ Logger.info("Can NOT find VDA with Id: " + sl20VDATypeHeader + ". Use default VDA");
+
+ }
+
+ Logger.info("NO SP specific VDA endpoint found. Use default VDA");
+ return endPointMap.getOrDefault(Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT,
+ Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID + Constants.CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT);
+
+ }
+
+}