aboutsummaryrefslogtreecommitdiff
path: root/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java
diff options
context:
space:
mode:
authorpdanner <pdanner@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c>2010-12-06 16:34:52 +0000
committerpdanner <pdanner@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c>2010-12-06 16:34:52 +0000
commit29ad090c29567ff1a4d3a2ec9b8ad0b5d80ee24d (patch)
tree5b75b34c822a79f70b83c266465dda70b9baeaf2 /pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java
parent04375406fc1634adbf9b37143a2125327da6a11e (diff)
downloadpdf-as-3-29ad090c29567ff1a4d3a2ec9b8ad0b5d80ee24d.tar.gz
pdf-as-3-29ad090c29567ff1a4d3a2ec9b8ad0b5d80ee24d.tar.bz2
pdf-as-3-29ad090c29567ff1a4d3a2ec9b8ad0b5d80ee24d.zip
git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@671 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c
Diffstat (limited to 'pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java')
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java342
1 files changed, 342 insertions, 0 deletions
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java
new file mode 100644
index 0000000..779b37b
--- /dev/null
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/SignServletHelper.java
@@ -0,0 +1,342 @@
+/**
+ *
+ */
+package at.gv.egiz.pdfas.web.helper;
+
+import java.io.IOException;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.pdfas.api.PdfAs;
+import at.gv.egiz.pdfas.api.commons.Constants;
+import at.gv.egiz.pdfas.api.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.api.internal.PdfAsInternal;
+import at.gv.egiz.pdfas.api.io.DataSink;
+import at.gv.egiz.pdfas.api.sign.SignParameters;
+import at.gv.egiz.pdfas.api.sign.SignResult;
+import at.gv.egiz.pdfas.api.sign.SignatureDetailInformation;
+import at.gv.egiz.pdfas.web.FormFields;
+import at.gv.egiz.pdfas.web.PDFContainer;
+import at.gv.egiz.pdfas.web.io.ByteArrayDataSink;
+import at.gv.egiz.pdfas.web.servlets.ProvidePDFServlet;
+import at.gv.egiz.pdfas.web.session.SessionAttributes;
+import at.gv.egiz.pdfas.web.session.SignSessionInformation;
+import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException;
+
+/**
+ * @author wprinz
+ *
+ */
+public class SignServletHelper
+{
+ /**
+ * The log.
+ */
+ private static Log log = LogFactory.getLog(SignServletHelper.class);
+
+ public static void dispatch(HttpServletRequest request, HttpServletResponse response, String resource, ServletContext context) throws ServletException, IOException
+ {
+ response.setContentType("text/html");
+ response.setCharacterEncoding("UTF-8");
+
+ RequestDispatcher disp = context.getRequestDispatcher(resource);
+ disp.forward(request, response);
+ }
+
+
+ /**
+ * Prepares the sign.
+ *
+ * <p>
+ * This prepares the data for both being signed or being previewed.
+ * </p>
+ *
+ * @param si
+ * The SessionInformation to be prepared.
+ * @throws PdfAsException
+ */
+ public static SignatureDetailInformation prepareSign(PdfAs pdfAs, SignSessionInformation si) throws PdfAsException
+ {
+ log.debug("prepareSign:"); //$NON-NLS-1$
+
+ SignParameters signParameters = new SignParameters();
+ signParameters.setDocument(si.pdfDataSource);
+ signParameters.setSignatureDevice(si.connector);
+ signParameters.setSignaturePositioning(si.pos);
+ signParameters.setSignatureProfileId(si.type);
+ signParameters.setSignatureType(si.mode);
+ DataSink sink = new ByteArrayDataSink();
+ signParameters.setOutput(sink);
+
+ SignatureDetailInformation signatureDetail = pdfAs.prepareSign(signParameters);
+ si.sdi = signatureDetail;
+ si.signParameters = signParameters;
+// PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode);
+// Signator signator = SignatorFactory.createSignator(algorithm);
+
+ // tzefferer: modified
+ // si.iui = signator.prepareSign(si.pdf, si.type, null,
+ // ConnectorFactory.needsSIG_ID(si.connector));
+// si.si = signator.prepareSign(si.pdfDataSource, si.type, si.pos, null);
+ // end modify
+ log.debug("prepareSign finished."); //$NON-NLS-1$
+ return signatureDetail;
+ }
+
+ /**
+ * Finishes the sign.
+ *
+ * <p>
+ * For non local connectors this concludes the sign process, signs the
+ * document and returns the result. For local connectors this initializes the
+ * local sign process and redirects to following servlets.
+ * </p>
+ *
+ * @param si
+ * The SessionInformation.
+ * @param request
+ * The servlet request for dispatching.
+ * @param response
+ * The servlet response for dispatching.
+ * @param context
+ * The servlet context for dispatching.
+ * @throws IOException
+ * f. e.
+ * @throws ServletException
+ * f. e.
+ * @throws PdfAsException
+ */
+ public static void finishSign(SignSessionInformation si, HttpServletRequest request, HttpServletResponse response, ServletContext context) throws IOException, ServletException, PdfAsException
+ {
+ log.debug("finishSign:"); //$NON-NLS-1$
+ PdfAs pdfAs = ApiHelper.getPdfAsFromContext(context);
+ PdfAsInternal pdfAsInternal = ApiHelper.getPdfAsInternalFromContext(context);
+
+ // check if document is empty
+ if (si.sdi.getSignatureData() == null || si.sdi.getSignatureData().getLength() == 0) {
+ throw new PDFDocumentException(251, "Unable to extract and textual content.");
+ }
+
+ log.debug("connector = " + si.connector); //$NON-NLS-1$
+ if (LocalRequestHelper.isConnectorLocal(si.connector))
+ {
+ log.debug("Connector is local -> dispatching to local processing."); //$NON-NLS-1$
+
+ String dispatch_to = LocalRequestHelper.processLocalSign(pdfAsInternal, si, request, response);
+ dispatch(request, response, dispatch_to, context);
+ return;
+ }
+ log.debug("Connector is not local -> finishing the sign."); //$NON-NLS-1$
+
+ ByteArrayDataSink data = new ByteArrayDataSink();
+ si.signParameters.setOutput(data);
+ SignResult signResult = pdfAs.sign(si.signParameters, si.sdi);
+ si.signResult = signResult;
+ si.signedPdf = data.getData();
+
+// PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode);
+// Signator signator = SignatorFactory.createSignator(algorithm);
+//
+// log.debug("RequestURL = " + request.getRequestURL());
+// log.debug("ContextPath = " + request.getContextPath());
+// String host = request.getServerName();
+
+ // TODO TR: Web-Applikation verwendet in Loc-Ref-Variante ext. Referenz, um performanter zu sein;
+ // nachfolend auskommentieren, wenn anstatt SwA-Connector LocRef-Connector verwendet wird
+// URL signature_data_URL = new URL(WebUtils.addJSessionID(LocalRequestHelper.getLocalContextAddress(request, response) + "/RetrieveSignatureData", request));
+// URL signature_data_URL = new URL(WebUtils.buildRetrieveSignatureDataURL(request, response));
+// String signature_data_url = response.encodeURL(signature_data_URL.toString());
+//
+// Connector c = ConnectorChooser.chooseWebConnectorForSign(si.connector, si.type, signature_data_url);
+// SignSignatureObject signSignatureObject = c.doSign(si.si.getSignatureData());
+//
+// si.si.setSignSignatureObject(signSignatureObject);
+
+// si.output = TempDirHelper.createTempDataSink(si.filename + "_signed.pdf");
+// signator.finishSign(si.si, si.output);
+
+ returnSignResponse(si, request, response);
+ log.debug("finishSign finished."); //$NON-NLS-1$
+
+ }
+
+ /**
+ * Returns the data in the SignResult with proper content disposition.
+ *
+ * @param si
+ * SessionInformation.
+ * @param bs
+ * @parem request The servlet request.
+ * @param response
+ * The servlet response.
+ * @throws IOException
+ * The IO Exception.
+ */
+ public static void returnSignResponse(SignSessionInformation si, HttpServletRequest request, HttpServletResponse response) throws IOException
+ {
+// SignResult sign_result = si.sign_result;
+
+ String file_name = formatFileNameForSignResult(si.filename, si.output.getMimeType());
+
+ // tzefferer: added condition
+ if (si.exappinf == null)
+ {
+
+ // The name parameter is actually deprecated in favour of
+ // Content-Disposition filename
+ // Unfortunately Acrobat reader does recognize neither of these parameters
+ // with its inline save-as. It always takes the page name.
+ response.setContentType(si.output.getMimeType() + "; name=\"" + file_name + "\"");
+ if (si.download_inline)
+ {
+ response.addHeader("Content-Disposition", "inline; filename=\"" + file_name + "\"");
+ }
+ else
+ {
+ response.addHeader("Content-Disposition", "attachment; filename=\"" + file_name + "\"");
+ }
+
+ IOUtils.write(si.signedPdf, response.getOutputStream());
+// TempDirHelper.writeDataSinkToHttpResponse(si.output, response);
+ //response.getOutputStream().write(sign_result.getData());
+
+ // tzefferer: added else-block
+ }
+ else
+ {
+ /**
+ * The following code handles an external invocation of pdf-as. External invocation is done by
+ * redirecting the user to the Sign-Servlet using the parameters defined in class
+ * at.knowcenter.wag.egov.egiz.web.FormFields.
+ * e.g. http://localhost:48080/pdf-as/Sign?preview=false&connector=bku&mode=textual&sig_type=SIGNATURBLOCK_DE&inline=false&filename=test.pdf&num-bytes=45916&pdf-url=http%3A%2F%2Flocalhost%3A8080%2Fmyapp%2FProvidePDF&pdf-id=1956507909008215134&invoke-app-url=https%3A%2F%2Flocalhost%3A8443%2Fmyapp%2FReturnSignedPDF&invoke-app-error-url=https%3A%2F%2Flocalhost%3A8443%2Fmyapp%2Fpdfaserror.do&session-id=9085B85B364BEC31E7D38047FE54577D&locale=de
+ */
+ log.debug("External webapp invocation detected.");
+ byte [] signed_pdf = si.signedPdf;
+// byte [] signed_pdf = null;
+// if (si.output instanceof FileBasedDataSink)
+// {
+// FileBasedDataSink fbds = (FileBasedDataSink)si.output;
+// signed_pdf = new byte [(int)fbds.getFile().length()];
+// FileInputStream fis = new FileInputStream(fbds.getFile());
+// fis.read(signed_pdf);
+// fis.close();
+// }
+// else
+// {
+// ByteArrayDataSink bads = (ByteArrayDataSink)si.output;
+// signed_pdf = bads.getByteArray();
+// }
+ HttpSession session = request.getSession();
+
+ PDFContainer entry = new PDFContainer(signed_pdf, si.exappinf.pdf_id);
+ ProvidePDFServlet.signedDocuments.add(entry);
+
+ // notify webapp...
+ String invoke_url = si.exappinf.invoke_url;
+
+ String providePDFServlet = "ProvidePDF";
+ String pdf_id = String.valueOf(si.exappinf.pdf_id);
+ String session_id = si.exappinf.session_id;
+
+ log.debug("External application has to be notified. Building url from callback url \"" + invoke_url + "\".");
+
+ // build URL
+ int ind = invoke_url.indexOf("?");
+
+ // fixed by tknall: must not presume that invoke_url contains "?"
+ String sep = "&";
+ if (ind == -1) {
+ ind = invoke_url.length();
+ sep = "?";
+ }
+
+ String query = invoke_url.substring(0, ind) + ";jsessionid=" + session_id + invoke_url.substring(ind)
+ + sep + FormFields.FIELD_PDF_URL + "=" + providePDFServlet + "&" + FormFields.FIELD_PDF_ID
+ + "=" + pdf_id + "&" + FormFields.FIELD_FILE_LENGTH + "=" + signed_pdf.length
+ + "&" + FormFields.FIELD_PDFAS_SESSION_ID + "=" + session.getId();
+
+ /*
+ * Using the external web-interface of pdf-as (as described above) pdf-as should be run within
+ * an iframe. In case of a signature performed with a local citizen card software or with the
+ * server bku the result has to be provided outside the iframe. To break out of the iframe a
+ * helper jsp (redirect_to_parent) has to be used that redirects the user to the parent
+ * window.
+ */
+ disableBrowserCacheForResponse(response);
+ if (Constants.SIGNATURE_DEVICE_BKU.equals(si.connector) || Constants.SIGNATURE_DEVICE_MOC.equals(si.connector)) {
+ log.debug("Pdf-as is supposed to run within an iframe.");
+ log.debug("Putting external application notify url (\"" + query + "\") in session (" + session.getId() + ") for later use.");
+ session.setAttribute(SessionAttributes.PARENT_WEBAPP_REDIRECT_URL, query);
+ String redirectHelper = response.encodeRedirectURL(request.getContextPath() + "/jsp/redirect_to_parent.jsp");
+
+ log.debug("Redirecting to " + redirectHelper);
+ log.debug("The browser will finally be redirected outside the iframe to " + query + " in order to notify the external application.");
+
+ response.sendRedirect(redirectHelper);
+
+ } else {
+ log.debug("Notifying external application by redirecting to \"" + query + "\".");
+ response.sendRedirect(query);
+ }
+
+ }
+
+ }
+
+ public static void disableBrowserCacheForResponse(HttpServletResponse response) {
+ log.debug("Disabling browser cache for HttpServletResponse.");
+ response.setHeader("Cache-Control", "no-cache");
+ response.setHeader("Pragma","no-cache");
+ response.setDateHeader("Expires", -1);
+ }
+
+ /**
+ * The Mime Type for XML.
+ */
+ public static final String XML_MIME_TYPE = "text/xml"; //$NON-NLS-1$
+
+ /**
+ * Formats the file name according to the SignResult.
+ *
+ * @param file_name
+ * The file name.
+ * @param sign_result
+ * The sign result.
+ * @return Returns the formatted file name.
+ */
+ public static String formatFileNameForSignResult(String file_name, String mimeType)
+ {
+ String output = file_name + "_signed";
+ if (mimeType.equals(XML_MIME_TYPE))
+ {
+ output += ".xml";
+ }
+ else
+ {
+ output += ".pdf";
+ }
+
+ return output;
+ }
+
+
+ public static void finishLocalSign(PdfAs pdfAs, PdfAsInternal pdfAsInternal, SignSessionInformation si) throws PdfAsException {
+ ByteArrayDataSink data = new ByteArrayDataSink();
+ si.signParameters.setOutput(data);
+
+ SignResult signResult = pdfAsInternal.finishLocalSign(pdfAs, si.signParameters, si.sdi, si.localBKUParams, si.xmlResponse);
+ si.signResult = signResult;
+ si.output = data;
+ si.outputAvailable = true;
+ si.signedPdf = data.getData();
+ }
+}