diff options
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java')
-rw-r--r-- | id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java new file mode 100644 index 000000000..d772a50c0 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java @@ -0,0 +1,218 @@ +package at.gv.egovernment.moa.id.auth.modules.stork.tasks;
+
+import iaik.x509.X509Certificate;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+
+import at.gv.egovernment.moa.id.auth.AuthenticationServer;
+import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.auth.stork.STORKException;
+import at.gv.egovernment.moa.id.commons.db.ConfigurationDBUtils;
+import at.gv.egovernment.moa.id.moduls.ModulUtils;
+import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage;
+import at.gv.egovernment.moa.id.util.VelocityProvider;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse;
+
+import com.datentechnik.process_engine.api.ExecutionContext;
+
+import eu.stork.oasisdss.api.ApiUtils;
+import eu.stork.oasisdss.profile.SignResponse;
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PersonalAttribute;
+
+/**
+ * Processes the citizen's signature, creates identity link using szr gateway and finalizes authentication.
+ * <p/>
+ * In detail:
+ * <ul>
+ * <li>Changes moa session id.</li>
+ * <li>Decodes and validates the sign response, extracting the citizen's signature.</li>
+ * <li>Verifies the citizen's signature.</li>
+ * <li>Create {@code signedDoc} attribute.</li>
+ * <li>Retrieve identity link from SZR gateway using the citizen's signature.</li>
+ * <li>If the S-PEPS did not provide any gender information, the szr gateway will not be able to issue an identity link.
+ * Therefore a form is presented asking for the subject's gender. The form finally submits the user back to the
+ * {@code /PepsConnectorWithLocalSigning} servlet (this task).</li>
+ * <li>The moa session is updated with authentication information.</li>
+ * <li>Change moa session id.</li>
+ * <li>Redirects back to {@code /dispatcher} in order to finalize the authentication.</li>
+ * </ul>
+ * Expects:
+ * <ul>
+ * <li>HttpServletRequest parameter {@code moaSessionID}</li>
+ * <li>HttpServletRequest parameter {@code signresponse}</li>
+ * </ul>
+ * Result:
+ * <ul>
+ * <li>Updated moa id session (signed auth block, signer certificate etc.)</li>
+ * <li>Redirect to {@code /dispatcher}.</li>
+ * <li>{@link ExecutionContext} contains boolean flag {@code identityLinkAvailable} indicating if an identitylink has been successfully creates or not.</li>
+ * </ul>
+ * Possible branches:
+ * <ul>
+ * <li>In case the szr gateway throws exception due to missing gender information:
+ * <ul>
+ * <li>Returns a form for gender selection with action url back to this servlet/task.</li>
+ * </ul>
+ * </li>
+ * </ul>
+ * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.PEPSConnectorWithLocalSigningServlet}.<br/>
+ *
+ * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse)
+ */
+public class PepsConnectorHandleLocalSignResponseTask extends AbstractPepsConnectorWithLocalSigningTask {
+
+ @Override
+ public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
+ throws Exception {
+ String moaSessionID = request.getParameter("moaSessionID");
+ String signResponse = request.getParameter("signresponse");
+ Logger.info("moaSessionID:" + moaSessionID);
+ Logger.info("signResponse:" + signResponse);
+
+ if (moaSessionID != null && signResponse != null) {
+ // redirect from oasis with signresponse
+ handleSignResponse(executionContext, request, response);
+ } else {
+ // should not occur
+ throw new IOException("should not occur");
+ }
+ return;
+ }
+
+ private void handleSignResponse(ExecutionContext executionContext, HttpServletRequest request,
+ HttpServletResponse response) {
+ Logger.info("handleSignResponse started");
+ String moaSessionID = request.getParameter("moaSessionID");
+ String signResponse = request.getParameter("signresponse");
+ Logger.info("moaSessionID:" + moaSessionID);
+ Logger.info("signResponse:" + signResponse);
+ String pendingRequestID = null;
+ try {
+
+ // load MOASession from database
+ AuthenticationSession moaSession = AuthenticationServer.getSession(moaSessionID);
+ // change MOASessionID
+ moaSessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
+
+ pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(moaSessionID);
+ Logger.info("pendingRequestID:" + pendingRequestID);
+ String signResponseString = new String(Base64.decodeBase64(signResponse), "UTF8");
+ Logger.info("RECEIVED signresponse:" + signResponseString);
+ // create SignResponse object
+ Source response1 = new StreamSource(new java.io.StringReader(signResponseString));
+ SignResponse dssSignResponse = ApiUtils.unmarshal(response1, SignResponse.class);
+
+ // SignResponse dssSignResponse = (SignResponse) ApiUtils.unmarshal(new StreamSource(new
+ // java.io.StringReader(Base64.signResponse)));
+
+ String citizenSignature = getCitizienSignatureFromSignResponse(dssSignResponse);
+
+ // memorize signature into authblock
+ moaSession.setAuthBlock(citizenSignature);
+
+ X509Certificate cert = getSignerCertificate(citizenSignature);
+ moaSession.setSignerCertificate(cert);
+ VerifyXMLSignatureResponse xMLVerifySignatureResponse = verifyXMLSignature(citizenSignature);
+ at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse tmp = convert(xMLVerifySignatureResponse);
+
+ moaSession.setXMLVerifySignatureResponse(tmp);
+ executionContext.put("identityLinkAvailable", false);
+ try {
+ IPersonalAttributeList personalAttributeList = moaSession.getAuthnResponseGetPersonalAttributeList();
+ // Add SignResponse TODO Add signature (extracted from signResponse)?
+ List<String> values = new ArrayList<String>();
+ values.add(signResponseString);
+ // values.add(citizenSignature);
+ Logger.debug("Assembling signedDoc attribute");
+ PersonalAttribute signedDocAttribute = new PersonalAttribute("signedDoc", false, values, "Available");
+ personalAttributeList.add(signedDocAttribute);
+
+ String authnContextClassRef = moaSession.getAuthnContextClassRef();
+ SZRGInsertion(moaSession, personalAttributeList, authnContextClassRef, citizenSignature);
+ executionContext.put("identityLinkAvailable", true);
+ } catch (STORKException e) {
+ // this is really nasty but we work against the system here. We are supposed to get the gender attribute
+ // from
+ // stork. If we do not, we cannot register the person in the ERnP - we have to have the
+ // gender for the represented person. So here comes the dirty hack.
+ if (e.getCause() instanceof STORKException
+ && e.getCause().getMessage().equals("gender not found in response")) {
+ try {
+ Logger.trace("Initialize VelocityEngine...");
+
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+ Template template = velocityEngine.getTemplate("/resources/templates/fetchGender.html");
+ VelocityContext context = new VelocityContext();
+ context.put("SAMLResponse", request.getParameter("SAMLResponse"));
+ context.put("action", request.getRequestURL());
+
+ StringWriter writer = new StringWriter();
+ template.merge(context, writer);
+ response.getOutputStream().write(writer.toString().getBytes("UTF-8"));
+ } catch (Exception e1) {
+ Logger.error("Error sending gender retrival form.", e1);
+ // httpSession.invalidate();
+ throw new MOAIDException("stork.10", null);
+ }
+
+ return;
+ }
+
+ Logger.error("Error connecting SZR Gateway", e);
+ throw new MOAIDException("stork.10", null);
+ }
+
+ Logger.debug("Add full STORK AuthnResponse to MOA session");
+ moaSession.setStorkAuthnResponse(request.getParameter("SAMLResponse"));// TODO ask Florian/Thomas
+ // authnResponse?
+ moaSession.setForeigner(true);
+
+ // session is implicit stored in changeSessionID!!!!
+ String newMOASessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
+
+ Logger.info("Changed MOASession " + moaSessionID + " to Session " + newMOASessionID);
+
+ // redirect
+ String redirectURL = null;
+ redirectURL = new DataURLBuilder().buildDataURL(moaSession.getAuthURL(),
+ ModulUtils.buildAuthURL(moaSession.getModul(), moaSession.getAction(), pendingRequestID),
+ newMOASessionID);
+ redirectURL = response.encodeRedirectURL(redirectURL);
+
+ response.sendRedirect(redirectURL);
+ Logger.info("REDIRECT TO: " + redirectURL);
+
+ } catch (AuthenticationException e) {
+ handleError(null, e, request, response, pendingRequestID);
+
+ } catch (MOAIDException e) {
+ handleError(null, e, request, response, pendingRequestID);
+
+ } catch (Exception e) {
+ Logger.error("PEPSConnector has an interal Error.", e);
+ }
+
+ finally {
+ ConfigurationDBUtils.closeSession();
+ }
+ }
+
+}
|