diff options
author | gregor <gregor@d688527b-c9ab-4aba-bd8d-4036d912da1d> | 2003-11-20 08:44:42 +0000 |
---|---|---|
committer | gregor <gregor@d688527b-c9ab-4aba-bd8d-4036d912da1d> | 2003-11-20 08:44:42 +0000 |
commit | 9149618d9049d470d0423c4e896ab6c127eb6c02 (patch) | |
tree | c103a1aabc756b75ec76e435d13013ffa388f4c3 /spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters | |
parent | 72819e05aa9db32ef828d9b35d8980a77d1bd76e (diff) | |
download | moa-id-spss-9149618d9049d470d0423c4e896ab6c127eb6c02.tar.gz moa-id-spss-9149618d9049d470d0423c4e896ab6c127eb6c02.tar.bz2 moa-id-spss-9149618d9049d470d0423c4e896ab6c127eb6c02.zip |
Erstellt.
git-svn-id: https://joinup.ec.europa.eu/svn/moa-idspss/trunk@59 d688527b-c9ab-4aba-bd8d-4036d912da1d
Diffstat (limited to 'spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters')
5 files changed, 547 insertions, 0 deletions
diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/RequestWrapper.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/RequestWrapper.java new file mode 100644 index 000000000..a6652a56e --- /dev/null +++ b/spss.slinterface/WEB-INF/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/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ResponseWrapper.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ResponseWrapper.java new file mode 100644 index 000000000..420723abb --- /dev/null +++ b/spss.slinterface/WEB-INF/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/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java new file mode 100644 index 000000000..4632c80f5 --- /dev/null +++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java @@ -0,0 +1,341 @@ +/* + * 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.InputStream; +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.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +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.Logger; +import org.apache.xerces.parsers.DOMParser; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; + +import at.gv.egovernment.moa.spss.slinterface.Constants; + +/** + * @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_; + private SLRequest slRequest_; + + /* ---------------------------------------------------------------------------------------------------- */ + + /** + * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) + */ + public void init(FilterConfig config) throws ServletException + { + // Store filter configuration + config_ = config; + + slRequest_ = new SLRequest(); + + // Initialize stylesheet transform SL2MOA + ServletContext context = config_.getServletContext(); + Transformer sl2MoaTransformer = (Transformer) context.getAttribute(Constants.WSCP_SL2MOA_TRANSFORMER_); + if (sl2MoaTransformer == null) + { + initTransformer(context, Constants.IP_SL2MOA_STYLESHEET_); + } + + // Initialize stylesheet transform MOA2SL + Transformer moa2SlTransformer = (Transformer) context.getAttribute(Constants.WSCP_MOA2SL_TRANSFORMER_); + if (moa2SlTransformer == null) + { + initTransformer(context, Constants.IP_MOA2SL_STYLESHEET_); + } + + } + + /* ---------------------------------------------------------------------------------------------------- */ + + /* + * @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 + { + // Check if request is HTTP-POST + checkHttpPost((HttpServletRequest) request); + + // Get SL request from content of request + parseRequest((HttpServletRequest) request); + + // Schema validate SL request + CharArrayReader slXmlRequestCAR = new CharArrayReader(slRequest_.xmlRequest_.toCharArray()); + Document slXMLRequestDoc = parseSlXmlRequest(slXmlRequestCAR); + + // Transform SL request into a MOA SPSS request + Transformer sl2MoaTransformer = + (Transformer) config_.getServletContext().getAttribute(Constants.WSCP_SL2MOA_TRANSFORMER_); + DOMSource slXMLRequestDS = new DOMSource(slXMLRequestDoc); + ByteArrayOutputStream moaRequestBOS = new ByteArrayOutputStream(); + StreamResult moaRequestResult = new StreamResult(moaRequestBOS); + try + { + sl2MoaTransformer.transform(slXMLRequestDS, moaRequestResult); + } + catch (TransformerException e) + { + String message = "Transforming SL XML request into MOA XML request failed."; + logger_.error(message, e); + throw new ServletException(message, e); + } + logger_.debug("MOA XML Request:\n" + moaRequestBOS.toString()); + ByteArrayInputStream moaRequestIS = new ByteArrayInputStream(moaRequestBOS.toByteArray()); + + // Invoke MOA SPSS + RequestWrapper requestWrapper = new RequestWrapper((HttpServletRequest) request, moaRequestIS); + ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response); + chain.doFilter(requestWrapper, responseWrapper); + + // Prepare response to client + response.setContentType("text/xml"); + + // Transform MOA response into a SL response and send SL response back to client + Transformer moa2SlTransformer = + (Transformer) config_.getServletContext().getAttribute(Constants.WSCP_MOA2SL_TRANSFORMER_); + ServletOutputStream moaResponseSOS = (ServletOutputStream) responseWrapper.getOutputStream(); + ByteArrayInputStream moaResponseBIS = new ByteArrayInputStream(moaResponseSOS.toByteArray()); + StreamSource moaResponseSource = new StreamSource(moaResponseBIS); + StreamResult slResponseResult = new StreamResult(response.getOutputStream()); + try + { + moa2SlTransformer.transform(moaResponseSource, slResponseResult); + } + catch (TransformerException e) + { + String message = "Transforming MOA XML response into SL XML response failed."; + logger_.error(message, e); + throw new ServletException(message, e); + } + } + + /* ---------------------------------------------------------------------------------------------------- */ + + /** + * @see javax.servlet.Filter#destroy() + */ + public void destroy() + { + // Nothing to do here at the moment. + } + + /* ---------------------------------------------------------------------------------------------------- */ + + 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 void parseRequest(HttpServletRequest request) throws IOException + { + // 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 combindation of XMLRequest and StylesheetURL allowed at the moment + String message = "Currently only (XMLRequest + DataURL) is supported."; + logger_.error(message); + throw new IOException(message); + } + } + + /* ---------------------------------------------------------------------------------------------------- */ + + 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); + } + + // 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); + } + } + + /* ---------------------------------------------------------------------------------------------------- */ + + /** + * Helper class, representing the fields of a Security-Layer request. + * + * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at) + */ + class SLRequest + { + public String xmlRequest_; + public String dataUrl_; + public String stylesheetUrl_; + public String redirectUrl_; + } +} diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletInputStream.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletInputStream.java new file mode 100644 index 000000000..b0609c2f8 --- /dev/null +++ b/spss.slinterface/WEB-INF/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/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletOutputStream.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/ServletOutputStream.java new file mode 100644 index 000000000..b790ee55c --- /dev/null +++ b/spss.slinterface/WEB-INF/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(); + } +} |