aboutsummaryrefslogtreecommitdiff
path: root/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters
diff options
context:
space:
mode:
Diffstat (limited to 'spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters')
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/RequestWrapper.java57
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ResponseWrapper.java44
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java381
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletInputStream.java55
-rw-r--r--spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletOutputStream.java50
5 files changed, 587 insertions, 0 deletions
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/RequestWrapper.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/RequestWrapper.java
new file mode 100644
index 000000000..a6652a56e
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/RequestWrapper.java
@@ -0,0 +1,57 @@
+/*
+ * Created on 19.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import java.io.ByteArrayInputStream;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class RequestWrapper extends HttpServletRequestWrapper
+{
+
+ private ServletInputStream inputStream_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Generates a request wrapper around a particular request.
+ *
+ * @param request The request to be wrapped.
+ *
+ * @param inputStream The new inputstream, which will be returned by method {@link #getInputStream}, and
+ * whose length will be returned by method {@link #getContentLength}.
+ */
+ public RequestWrapper(HttpServletRequest request, ByteArrayInputStream inputStream)
+ {
+ super(request);
+ inputStream_ = new ServletInputStream(inputStream);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see #RequestWrapper(HttpServletRequest, ByteArrayInputStream)
+ */
+ public javax.servlet.ServletInputStream getInputStream()
+ {
+ return inputStream_;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see #RequestWrapper(HttpServletRequest, ByteArrayInputStream)
+ */
+ public int getContentLength()
+ {
+ return inputStream_.getContentLength();
+ }
+
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ResponseWrapper.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ResponseWrapper.java
new file mode 100644
index 000000000..420723abb
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ResponseWrapper.java
@@ -0,0 +1,44 @@
+/*
+ * Created on 18.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class ResponseWrapper extends HttpServletResponseWrapper
+{
+ private ServletOutputStream outputStream_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public ResponseWrapper(HttpServletResponse response)
+ {
+ super(response);
+ outputStream_ = new ServletOutputStream();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ public javax.servlet.ServletOutputStream getOutputStream()
+ {
+ return outputStream_;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Returns the wrapped response as a byte array.
+ *
+ * @return the response as a byte array.
+ */
+ public byte[] toByteArray()
+ {
+ return outputStream_.toByteArray();
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java
new file mode 100644
index 000000000..0ff14551f
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java
@@ -0,0 +1,381 @@
+/*
+ * Created on 18.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.fileupload.DiskFileUpload;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileUpload;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.xerces.parsers.DOMParser;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import at.gv.egovernment.moa.spss.slinterface.Constants;
+import at.gv.egovernment.moa.spss.slinterface.beans.ChecksInfoBean;
+import at.gv.egovernment.moa.spss.slinterface.beans.DataInfoBean;
+import at.gv.egovernment.moa.spss.slinterface.beans.SignerInfoBean;
+import at.gv.egovernment.moa.spss.slinterface.moainvoker.MOAInvoker;
+import at.gv.egovernment.moa.spss.slinterface.servlets.SLRequest;
+import at.gv.egovernment.moa.spss.slinterface.transformers.MOA2SL;
+import at.gv.egovernment.moa.spss.slinterface.transformers.SL2MOA;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class SL2MOAFilter implements Filter
+{
+ private static Logger logger_ = Logger.getLogger(Constants.LH_FILTERS_);
+
+ private FilterConfig config_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+ */
+ public void init(FilterConfig config) throws ServletException
+ {
+ // Store filter configuration
+ config_ = config;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
+ * javax.servlet.FilterChain)
+ */
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException
+ {
+ // It is necessary to set the content type header already here, because for any unknown reason setting
+ // it in the response JSP page has no effects at all. Perhaps any of the filters or the like already
+ // writes to the response output stream.
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
+ httpResponse.setHeader("Content-Type", "text/html; charset='ISO-8859-1'");
+
+ // Create session
+ HttpSession session = ((HttpServletRequest) request).getSession(true);
+
+ // Check if request is HTTP-POST
+ checkHttpPost((HttpServletRequest) request);
+
+ // Remember remote IP address for later URL rewriting
+ session.setAttribute("remoteAddr", request.getRemoteAddr());
+
+ // Get SL request from content of request
+ SLRequest slRequest = parseRequest((HttpServletRequest) request);
+ session.setAttribute("slRequest", slRequest);
+
+ // Schema validate SL request
+ CharArrayReader slXmlRequestCAR = new CharArrayReader(slRequest.xmlRequest_.toCharArray());
+ Document slXMLRequestDoc = parseSlXmlRequest(slXmlRequestCAR);
+ logger_.debug("Finnished schema validating SL request.");
+
+ // Transform SL request into a MOA SPSS request
+ Properties initProps = (Properties)config_.getServletContext().getAttribute(Constants.WSCP_INIT_PROPS_);
+ String trustProfileId = initProps.getProperty(Constants.IP_SP_TRUSTPROFILEID_);
+ Document moaXMLRequestDoc = SL2MOA.toMoaVerifyXMLSignatureRequest(slXMLRequestDoc, trustProfileId);
+ ByteArrayOutputStream moaRequestBOS = new ByteArrayOutputStream();
+ MOAInvoker.serializeDocument(moaXMLRequestDoc, moaRequestBOS);
+ logger_.debug("SL request transformed into MOA request:\n" + moaRequestBOS);
+ ByteArrayInputStream moaRequestIS = new ByteArrayInputStream(moaRequestBOS.toByteArray());
+ logger_.debug("Finnished transforming SL request into a MOA SP request.");
+
+ // Invoke MOA SPSS
+ RequestWrapper requestWrapper = new RequestWrapper((HttpServletRequest) request, moaRequestIS);
+ ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response);
+ chain.doFilter(requestWrapper, responseWrapper);
+ logger_.debug("Finnished invoking MOA SP service.");
+
+ // Parse MOA response
+ DOMParser xmlParser = (DOMParser) config_.getServletContext().getAttribute(Constants.WSCP_XMLPARSER_);
+ ServletOutputStream moaResponseSOS = (ServletOutputStream) responseWrapper.getOutputStream();
+ ByteArrayInputStream moaResponseBIS = new ByteArrayInputStream(moaResponseSOS.toByteArray());
+ InputSource responseSource = new InputSource(moaResponseBIS);
+ Document moaResponseDoc;
+ try
+ {
+ xmlParser.parse(responseSource);
+ moaResponseDoc = xmlParser.getDocument();
+ }
+ catch (SAXException e)
+ {
+ String message = "Parsing MOA XML response failed.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ logger_.debug("Finnished parsing MOA SP response.");
+
+ // Create bean with info about signed data
+ try
+ {
+ DataInfoBean dataInfo = new DataInfoBean(
+ moaXMLRequestDoc,
+ moaResponseDoc,
+ ((HttpServletRequest) request).getContextPath(),
+ session,
+ config_.getServletContext());
+ session.setAttribute("dataInfo", dataInfo);
+ }
+ catch (Exception e)
+ {
+ String message = "Creating DataInfobean failed.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ logger_.debug("Finnished creating bean with info about signed data.");
+
+ // Transform MOA response into a SL response
+ Document slResponseDoc;
+ slResponseDoc = MOA2SL.toSlVerifyXMLSignatureResponse(moaResponseDoc);
+ session.setAttribute("slResponseDoc", slResponseDoc);
+ logger_.debug("Finnished transforming MOA SP response into a SL response.");
+
+ // Create bean with info about signer
+ SignerInfoBean signerInfo = new SignerInfoBean(slResponseDoc);
+ request.setAttribute("signerInfo", signerInfo);
+ logger_.debug("Finnished creating bean with info about signer.");
+
+ // Create bean with info about checks
+ ChecksInfoBean checksInfo = new ChecksInfoBean(slResponseDoc);
+ request.setAttribute("checksInfo", checksInfo);
+ logger_.debug("Finnished creating bean with info about checks.");
+
+ // Include jsp page, which writes the overview information about the verified signature
+ try
+ {
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/pages/resultOverview.jsp");
+ dispatcher.include(request, response);
+ }
+ catch (IOException e)
+ {
+ String message = "Failed to create result overview page.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ logger_.debug("Finnished SL2MOAFilter.");
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see javax.servlet.Filter#destroy()
+ */
+ public void destroy()
+ {
+ // Nothing to do here at the moment.
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ // TODO Revisit if method can be removed
+ /* private void initTransformer(ServletContext context, String initPropStylesheetLoc) throws ServletException
+ {
+ String stylesheetName =
+ (Constants.IP_SL2MOA_STYLESHEET_.equals(initPropStylesheetLoc))
+ ? "sl2Moa"
+ : "moa2Sl";
+
+ String contextAttrName =
+ (Constants.IP_SL2MOA_STYLESHEET_.equals(initPropStylesheetLoc))
+ ? Constants.WSCP_SL2MOA_TRANSFORMER_
+ : Constants.WSCP_MOA2SL_TRANSFORMER_;
+
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ Properties initProps = (Properties) context.getAttribute(Constants.WSCP_INIT_PROPS_);
+ String stylesheetLoc = initProps.getProperty(initPropStylesheetLoc);
+ InputStream stylesheetIS = context.getResourceAsStream(stylesheetLoc);
+ if (stylesheetIS == null)
+ {
+ String message =
+ "Cannot load " + stylesheetName + " stylesheet from location \"" + stylesheetLoc + "\".";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+ Transformer transformer;
+ try
+ {
+ StreamSource stylesheetSS = new StreamSource(stylesheetIS);
+ transformer = transformerFactory.newTransformer(stylesheetSS);
+ }
+ catch (TransformerConfigurationException e)
+ {
+ String message = "Cannot create XSLT transformer with " + stylesheetName + " stylesheet.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ context.setAttribute(contextAttrName, transformer);
+ }*/
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Parses the http request.
+ */
+ private SLRequest parseRequest(HttpServletRequest request) throws IOException
+ {
+ SLRequest slRequest = new SLRequest();
+
+ // Check if request URL ends with "http-security-layer-request"
+ // @TODO Don't know if this check is sufficient - spec says request URL must have this value as path
+ String requestURI = request.getRequestURI();
+ if (!requestURI.endsWith(Constants.SLC_NAME_HTTP_REQUEST_))
+ {
+ String message = "Request does not end with \"" + Constants.SLC_NAME_HTTP_REQUEST_ + "\".";
+ logger_.error(message);
+ throw new IOException(message);
+ }
+
+ if (FileUpload.isMultipartContent(request))
+ {
+ // Request is encoded as mulitpart/form-data
+ List items;
+ try
+ {
+ DiskFileUpload upload = new DiskFileUpload();
+ items = upload.parseRequest(request);
+ }
+ catch (FileUploadException e)
+ {
+ String message = "Cannot parse multipart/form-data request.";
+ logger_.error(message);
+ throw new IOException(message);
+ }
+
+ Iterator itemsIt = items.iterator();
+ while (itemsIt.hasNext())
+ {
+ FileItem currItem = (FileItem) itemsIt.next();
+ String currItemName = currItem.getFieldName();
+ if (Constants.SLC_NAME_XML_REQUEST_.equals(currItemName))
+ slRequest.xmlRequest_ = currItem.getString();
+ else if (Constants.SLC_NAME_DATA_URL_.equals(currItemName))
+ slRequest.dataUrl_ = currItem.getString();
+ else if (Constants.SLC_NAME_STYLESHEET_URL_.equals(currItemName))
+ slRequest.stylesheetUrl_ = currItem.getString();
+ else if (Constants.SLC_NAME_REDIRECT_URL_.equals(currItemName))
+ slRequest.redirectUrl_ = currItem.getString();
+ else
+ continue; // @TODO Do not evaluate other params at the moment
+ }
+ }
+ else
+ {
+ // Request is encoded as application/x-www-form-urlencoded
+ Map paramsMap = request.getParameterMap();
+ Iterator paramNames = paramsMap.keySet().iterator();
+ while (paramNames.hasNext())
+ {
+ String currName = (String) paramNames.next();
+ String[] currValues = (String[]) paramsMap.get(currName);
+ if (Constants.SLC_NAME_XML_REQUEST_.equals(currName))
+ slRequest.xmlRequest_ = currValues[0];
+ else if (Constants.SLC_NAME_DATA_URL_.equals(currName))
+ slRequest.dataUrl_ = currValues[0];
+ else if (Constants.SLC_NAME_STYLESHEET_URL_.equals(currName))
+ slRequest.stylesheetUrl_ = currValues[0];
+ else if (Constants.SLC_NAME_REDIRECT_URL_.equals(currName))
+ slRequest.redirectUrl_ = currValues[0];
+ else
+ continue; // @TODO Do not evaluate other params at the moment
+ }
+ }
+
+ if (slRequest.xmlRequest_ == null || slRequest.dataUrl_ == null ||
+ slRequest.stylesheetUrl_ != null || slRequest.redirectUrl_ != null)
+ {
+ // @TODO Only combination of XMLRequest and DataURL allowed at the moment
+ String message = "Currently only (XMLRequest + DataURL) is supported.";
+ logger_.error(message);
+ throw new IOException(message);
+ }
+
+ return slRequest;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private Document parseSlXmlRequest(Reader slXmlRequest) throws ServletException
+ {
+ // Parse sl request
+ InputSource slXMLRequestIS = new InputSource(slXmlRequest);
+ Document slXmlRequestDoc = null;
+ try
+ {
+ DOMParser xmlParser = (DOMParser) config_.getServletContext().getAttribute(Constants.WSCP_XMLPARSER_);
+ xmlParser.parse(slXMLRequestIS);
+ slXmlRequestDoc = xmlParser.getDocument();
+ }
+ catch (Exception e)
+ {
+ String message = "Parsing Security-Layer request failed.";
+ logger_.error(message, e);
+ throw new ServletException(message, e);
+ }
+ if (logger_.getEffectiveLevel().isGreaterOrEqual(Level.DEBUG))
+ {
+ ByteArrayOutputStream debugOutputStream = new ByteArrayOutputStream();
+ try
+ {
+ MOAInvoker.serializeDocument(slXmlRequestDoc, debugOutputStream);
+ logger_.debug("XML-Request received:\n" + debugOutputStream);
+ }
+ catch (IOException e)
+ {
+ // No debug output if this fails
+ }
+ }
+
+ // Check if namespace is correct
+ String namespaceURI = slXmlRequestDoc.getDocumentElement().getNamespaceURI();
+ if (!Constants.NSURI_SL_11_.equals(namespaceURI) && !Constants.NSURI_SL_12_.equals(namespaceURI))
+ {
+ String message = "XML request has invalid namespace: \"" + namespaceURI + "\".";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+
+ return slXmlRequestDoc;
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ private void checkHttpPost(HttpServletRequest request) throws ServletException
+ {
+ String method = request.getMethod();
+ if (!"POST".equals(method))
+ {
+ String message = "HTTP method \"" + method + "\" not supported. Must be \"POST\".";
+ logger_.error(message);
+ throw new ServletException(message);
+ }
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletInputStream.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletInputStream.java
new file mode 100644
index 000000000..b0609c2f8
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletInputStream.java
@@ -0,0 +1,55 @@
+/*
+ * Created on 19.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class ServletInputStream extends javax.servlet.ServletInputStream
+{
+ private ByteArrayInputStream inputStream_;
+ private int length_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Generates a new <code>ServletInputStram</code> from the specified stream.
+ *
+ * @param inputStream See above.
+ */
+ public ServletInputStream(ByteArrayInputStream inputStream)
+ {
+ super();
+ inputStream_ = inputStream;
+ length_ = inputStream_.available();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Reads a single byte from the underlying <code>ByteArrayInputStream</code>.
+ *
+ * @see java.io.InputStream#read()
+ */
+ public int read() throws IOException
+ {
+ return inputStream_.read();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Gets the length of the content from this input stream. This equals to the number of bytes which where
+ * available at the time of creating this <code>ServletInputStream</code>.
+ */
+ public int getContentLength()
+ {
+ return length_;
+ }
+}
diff --git a/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletOutputStream.java b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletOutputStream.java
new file mode 100644
index 000000000..b790ee55c
--- /dev/null
+++ b/spss.slinterface/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletOutputStream.java
@@ -0,0 +1,50 @@
+/*
+ * Created on 18.11.2003
+ *
+ * (c) Stabsstelle IKT-Strategie des Bundes
+ */
+package at.gv.egovernment.moa.spss.slinterface.filters;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
+ */
+public class ServletOutputStream extends javax.servlet.ServletOutputStream
+{
+ private ByteArrayOutputStream outputStream_;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Default constructor.
+ */
+ public ServletOutputStream()
+ {
+ super();
+ outputStream_ = new ByteArrayOutputStream();
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * @see java.io.OutputStream#write(int)
+ */
+ public void write(int b) throws IOException
+ {
+ outputStream_.write(b);
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
+ /**
+ * Returns the content of this stream as a byte array.
+ *
+ * @return the content of this stream as a byte array.
+ */
+ public byte[] toByteArray()
+ {
+ return outputStream_.toByteArray();
+ }
+}