package at.gv.egovernment.moa.id.auth.modules.internal.tasks;
import static at.gv.egovernment.moa.id.commons.MOAIDAuthConstants.PARAM_XMLRESPONSE;
import static at.gv.egovernment.moa.id.commons.MOAIDAuthConstants.REQ_VERIFY_AUTH_BLOCK;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.TransformerException;
import org.apache.commons.fileupload.FileUploadException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.w3c.dom.Element;
import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
import at.gv.egovernment.moa.id.auth.AuthenticationServer;
import at.gv.egovernment.moa.id.auth.data.CreateXMLSignatureResponse;
import at.gv.egovernment.moa.id.auth.exception.ParseException;
import at.gv.egovernment.moa.id.auth.exception.WrongParametersException;
import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;
import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
import at.gv.egovernment.moa.id.auth.parser.CreateXMLSignatureResponseParser;
import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser;
import at.gv.egovernment.moa.id.client.SZRGWClientException;
import at.gv.egovernment.moa.id.client.utils.SZRGWClientUtils;
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.pvp2x.PVPConstants;
import at.gv.egovernment.moa.id.util.ParamValidatorUtils;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.DOMUtils;
import at.gv.util.xsd.srzgw.CreateIdentityLinkResponse;
/**
* Evaluates the {@code CreateXMLSignatureResponse}, extracts signature and certificate and asks the SZR Gateway for an identity link.
* In detail:
*
* - Renames the moa session id.
* - Parses the CreateXMLSignatureResponse retrieved from POST parameter {@linkplain at.gv.egovernment.moa.id.commons.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE}.
* - Extracts signature and signer certificate.
* - Send request to SZR Gateway in order to get an identity link.
* - Updates moa session (sets identity link, QAA level 4, authentication data and foreigner flag).
* - Redirects back to {@code /dispatcher} in order to finalize authentication.
*
* Expects:
*
* - HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.commons.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}
* - HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.commons.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE} containing a {@code CreateXMLSignatureResponse}.
*
* Result:
*
* - Identity link, QAA level 4 and foreigner flag put into moa session.
* - Redirect to {@code /dispatcher}.
*
* Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.GetForeignIDServlet}.
* @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse)
*
*/
@Component("GetForeignIDTask")
public class GetForeignIDTask extends AbstractAuthServletTask {
@Autowired @Qualifier("CitizenCardAuthenticationServer") private AuthenticationServer authServer;
@Override
public void execute(ExecutionContext executionContext, HttpServletRequest req, HttpServletResponse resp)
throws TaskExecutionException {
Logger.debug("POST GetForeignIDServlet");
Map parameters;
try {
parameters = getParameters(req);
} catch (FileUploadException | IOException e) {
Logger.error("Parsing mulitpart/form-data request parameters failed: " + e.getMessage());
throw new TaskExecutionException(pendingReq, "Parsing mulitpart/form-data request parameters failed", new IOException(e.getMessage()));
}
try {
//check if response exists
String xmlCreateXMLSignatureResponse = (String) parameters.get(PARAM_XMLRESPONSE);
if (!ParamValidatorUtils.isValidXMLDocument(xmlCreateXMLSignatureResponse)) {
throw new WrongParametersException("GetForeignID", PARAM_XMLRESPONSE, "auth.12");
}
Logger.debug(xmlCreateXMLSignatureResponse);
//execute default task initialization
defaultTaskInitialization(req, executionContext);
CreateXMLSignatureResponse csresp = new CreateXMLSignatureResponseParser(xmlCreateXMLSignatureResponse)
.parseResponseDsig();
try {
String serializedAssertion = DOMUtils.serializeNode(csresp.getDsigSignature());
moasession.setAuthBlock(serializedAssertion);
} catch (TransformerException e) {
throw new ParseException("parser.04", new Object[] { REQ_VERIFY_AUTH_BLOCK, PARAM_XMLRESPONSE });
} catch (IOException e) {
throw new ParseException("parser.04", new Object[] { REQ_VERIFY_AUTH_BLOCK, PARAM_XMLRESPONSE });
}
Element signature = csresp.getDsigSignature();
try {
moasession.setSignerCertificate(AuthenticationServer.getCertificateFromXML(signature));
} catch (CertificateException e) {
Logger.error("Could not extract certificate from CreateXMLSignatureResponse");
throw new MOAIDException("auth.14", null);
}
revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(),
pendingReq, MOAIDEventConstants.AUTHPROCESS_FOREIGN_SZRGW_CONNECTED);
// make SZR request to the identity link
CreateIdentityLinkResponse response = SZRGWClientUtils.getIdentityLink(pendingReq, signature);
if (null != response.getErrorResponse()) {
// TODO fix exception parameter
throw new SZRGWClientException("service.08", (String) response.getErrorResponse().getErrorCode(),
(String) response.getErrorResponse().getInfo());
} else {
IdentityLinkAssertionParser ilParser = new IdentityLinkAssertionParser(new ByteArrayInputStream(
response.getIdentityLink()));
IIdentityLink identitylink = ilParser.parseIdentityLink();
moasession.setIdentityLink(identitylink);
// set QAA Level four in case of card authentifcation
moasession.setQAALevel(PVPConstants.STORK_QAA_1_4);
authServer.getForeignAuthenticationData(moasession);
revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(),
pendingReq, MOAIDEventConstants.AUTHPROCESS_FOREIGN_SZRGW_RECEIVED);
//store pending request
requestStoreage.storePendingRequest(pendingReq);
}
} catch (MOAIDException ex) {
throw new TaskExecutionException(pendingReq, ex.getMessage(), ex);
} catch (Exception e) {
Logger.error("GetForeignIDServlet has an interal Error.", e);
throw new TaskExecutionException(pendingReq, e.getMessage(), e);
}
}
}