diff options
Diffstat (limited to 'spss.server/src/at/gv/egovernment/moa')
6 files changed, 367 insertions, 20 deletions
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/init/SystemInitializer.java b/spss.server/src/at/gv/egovernment/moa/spss/server/init/SystemInitializer.java index f968778d7..4871ac4fe 100644 --- a/spss.server/src/at/gv/egovernment/moa/spss/server/init/SystemInitializer.java +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/init/SystemInitializer.java @@ -5,6 +5,8 @@ import java.security.Security; import javax.net.ssl.SSLSocketFactory; +import org.apache.axis.AxisProperties; + import iaik.ixsil.init.IXSILInit; import at.gv.egovernment.moa.logging.LogMsg; @@ -67,6 +69,11 @@ public class SystemInitializer { "com.sun.net.ssl.internal.www.protocol"); SSLSocketFactory.getDefault(); + +// AxisProperties.setProperty("enableNamespacePrefixOptimization","false"); +// AxisProperties.setProperty("disablePrettyXML", "true"); +// AxisProperties.setProperty("axis.doAutoTypes", "true"); + // initialize preparsed Xerces grammar pool for faster XML // parsing/validating try { diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java index 806b76409..106742067 100644 --- a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java @@ -1,5 +1,8 @@ package at.gv.egovernment.moa.spss.server.invoke; +import iaik.ixsil.exceptions.URIException; +import iaik.ixsil.util.URI; + import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; @@ -7,10 +10,9 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; -import iaik.ixsil.exceptions.URIException; -import iaik.ixsil.util.URI; - import at.gv.egovernment.moa.spss.MOAApplicationException; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; /** * Resolve external URIs and provide them as a stream. @@ -52,6 +54,39 @@ public class ExternalURIResolver { throw new MOAApplicationException("2213", new Object[] { uriStr }); } + // if we have local content (SOAP with attachments) + if ("formdata".equals(uri.getScheme())) { + TransactionContext context = TransactionContextManager.getInstance().getTransactionContext(); + if (context==null) { + //no transaction + throw new MOAApplicationException("2282", new Object[] { uri }); + } else { + + InputStream attachmentIs = context.getAttachmentInputStream(uri); + if (attachmentIs != null) { + setContentType(context.getAttachmentContentType(uri.getPath())); + return attachmentIs; + } else { + //maybe attachments provided but no suiting attachment found + throw new MOAApplicationException("2282", new Object[] { uri }); + } +/* + try { + InputStream attachmentIs = context.getAttachment(uri).getInputStream(); + if (attachmentIs != null) { + setContentType(context.getAttachmentContentType(uri.getPath())); + return attachmentIs; + } else { + //maybe attachments provided but no suiting attachment found + throw new MOAApplicationException("2282", new Object[] { uri }); + } + } catch (IOException e) { + throw new MOAApplicationException("2208", new Object[] { uri }, e); + } +*/ + } + } + // convert URI to URL try { // create the URL diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/AxisHandler.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/AxisHandler.java index 64bbb8dbe..985012da2 100644 --- a/spss.server/src/at/gv/egovernment/moa/spss/server/service/AxisHandler.java +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/AxisHandler.java @@ -1,34 +1,39 @@ package at.gv.egovernment.moa.spss.server.service; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.security.cert.X509Certificate; +import java.util.Iterator; import javax.servlet.http.HttpServletRequest; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - import org.apache.axis.AxisFault; +import org.apache.axis.Message; import org.apache.axis.MessageContext; +import org.apache.axis.attachments.AttachmentPart; import org.apache.axis.handlers.BasicHandler; import org.apache.axis.transport.http.HTTPConstants; import org.apache.axis.utils.Messages; import org.apache.axis.utils.XMLUtils; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import at.gv.egovernment.moa.logging.LogMsg; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.logging.LoggingContext; import at.gv.egovernment.moa.logging.LoggingContextManager; - import at.gv.egovernment.moa.spss.MOASystemException; import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; import at.gv.egovernment.moa.spss.server.transaction.TransactionIDGenerator; import at.gv.egovernment.moa.spss.util.MessageProvider; +import at.gv.egovernment.moa.util.DOMUtils; /** * An handler that is invoked on each web service request and performs some @@ -44,7 +49,7 @@ import at.gv.egovernment.moa.spss.util.MessageProvider; public class AxisHandler extends BasicHandler { /** The resource names of the messages to load. */ - private static final String MOA_SPSS_WSDL_RESOURCE_ = "/resources/wsdl/MOA-SPSS-1.2.wsdl"; + private static final String MOA_SPSS_WSDL_RESOURCE_ = "/resources/wsdl/MOA-SPSS-1.3.wsdl"; /** The property name for accessing the HTTP request. */ private static final String REQUEST_PROPERTY = HTTPConstants.MC_HTTP_SERVLETREQUEST; @@ -55,6 +60,18 @@ public class AxisHandler extends BasicHandler { /** The property name for accessing the SOAP action header. */ private static final String SOAP_ACTION_HEADER = "soapaction"; + /** URI of the SOAP XML namespace. */ + public static final String SOAP_NS_URI = "http://schemas.xmlsoap.org/soap/envelope/"; + + /** Prefix used for the SOAP XML namespace */ + public static final String SOAP_PREFIX = "soapenv"; + + /** Simple string contains the front part of the enveloping SOAP wrapping */ + private static final String SOAP_PART_PRE = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><soapenv:Body>"; + + /** Simple string contains the post part of the enveloping SOAP wrapping */ + private static final String SOAP_PART_POST = "</soapenv:Body></soapenv:Envelope>"; + /** * Handle an invocation of this handler. * @@ -86,16 +103,68 @@ public class AxisHandler extends BasicHandler { X509Certificate[] clientCert = (X509Certificate[]) request.getAttribute(X509_CERTIFICATE_PROPERTY); + //Configure Axis + //msgContext.setProperty(org.apache.axis.SOAPPart.ALLOW_FORM_OPTIMIZATION, Boolean.FALSE); + + Message soapMessage = msgContext.getCurrentMessage(); + ConfigurationProvider configuration = ConfigurationProvider.getInstance(); + Element xmlRequest = null; + Element soapPart = DOMUtils.parseDocument(new ByteArrayInputStream(soapMessage.getSOAPPartAsBytes()), false, null, null).getDocumentElement(); + if (soapPart!=null) { + NodeList soapBodies = soapPart.getElementsByTagNameNS(SOAP_NS_URI, "Body"); + if (soapBodies!=null && soapBodies.getLength()>0) { + xmlRequest = (Element) soapBodies.item(0).getFirstChild(); + } + //oder TODO: Evaluierung ob XPATH schneller + /* + HashMap nSMap = new HashMap(); + nSMap.put((String)SOAP_PREFIX, SOAP_NS_URI); + Element soapBody = (Element) XPathUtils.selectSingleNode(soapPart, nSMap, "/"+SOAP_PREFIX+":Envelope/"+SOAP_PREFIX+":Body"); + if (soapBody!=null) { + xmlRequest= (Element) soapBody.getFirstChild(); + } + */ + } + TransactionContext context = new TransactionContext( TransactionIDGenerator.nextID(), clientCert, - configuration); + configuration, + xmlRequest, + null); + + String soapAction = (String) request.getHeader(SOAP_ACTION_HEADER); + if ("\"\"".equals(soapAction)) { + // if http soap action header is empty + soapAction = msgContext.getTargetService(); + } + context.setRequestName(soapAction); - context.setRequestName((String) request.getHeader(SOAP_ACTION_HEADER)); + int attachmentCount = soapMessage.getAttachmentsImpl().getAttachmentCount(); + if (attachmentCount>0) { + + // add SOAP attachments to transaction context + Iterator iterator = soapMessage.getAttachments(); + while (iterator.hasNext()) { + AttachmentPart attachment = (AttachmentPart)iterator.next(); + String id = attachment.getContentId(); + String type = attachment.getContentType(); + + //Now get the InputStream (note: we could also get the content with Object content = attachment.getContent();) + InputStream is = null; + javax.activation.DataHandler datahandler = attachment.getDataHandler(); + org.apache.axis.attachments.ManagedMemoryDataSource mmds = (org.apache.axis.attachments.ManagedMemoryDataSource)datahandler.getDataSource(); + if (mmds!=null){ + is = mmds.getInputStream(); + } + debug("handler.06", new Object[] {id, type}); + context.addAttachment(id, type, mmds); + } + } setUpContexts(context); @@ -118,7 +187,7 @@ public class AxisHandler extends BasicHandler { info("handler.03", null); } if (Logger.isDebugEnabled()) { - String msg = msgContext.getCurrentMessage().getSOAPPartAsString(); + String msg = soapMessage.getSOAPPartAsString(); Logger.debug(new LogMsg(msg)); } } catch (MOASystemException e) { @@ -127,6 +196,8 @@ public class AxisHandler extends BasicHandler { fault.setFaultDetail(new Element[] { se.toErrorResponse()}); throw fault; } catch (Throwable t) { + t.printStackTrace(); + Logger.info(new LogMsg(t.getStackTrace())); MOASystemException e = new MOASystemException("2900", null, t); AxisFault fault = AxisFault.makeFault(e); fault.setFaultDetail(new Element[] { e.toErrorResponse()}); @@ -142,10 +213,35 @@ public class AxisHandler extends BasicHandler { * @throws AxisFault An error occurred during processing of the response. */ private void handleResponse(MessageContext msgContext) throws AxisFault { + String xmlResponseString = null; + String soapResponseString = null; + + TransactionContext context = TransactionContextManager.getInstance().getTransactionContext(); + Element xmlResponse = context.getResponse(); + + if (xmlResponse!=null) { + try { + xmlResponseString = DOMUtils.serializeNode(xmlResponse, true); + soapResponseString = SOAP_PART_PRE + xmlResponseString + SOAP_PART_POST; + //override axis response-message + msgContext.setResponseMessage(new Message(soapResponseString)); + } catch (Throwable t) { + t.printStackTrace(); + Logger.info(new LogMsg(t.getStackTrace())); + MOASystemException e = new MOASystemException("2900", null, t); + AxisFault fault = AxisFault.makeFault(e); + fault.setFaultDetail(new Element[] { e.toErrorResponse()}); + throw fault; + } + + } else { + //Fallback: if functions do not set the resulting response in the transaction, the original one from axis will be used + xmlResponseString = msgContext.getCurrentMessage().getSOAPPartAsString(); + } + info("handler.04", null); if (Logger.isDebugEnabled()) { - String msg = msgContext.getCurrentMessage().getSOAPPartAsString(); - Logger.debug(new LogMsg(msg)); + Logger.debug(new LogMsg(xmlResponseString)); } tearDownContexts(); } @@ -183,8 +279,13 @@ public class AxisHandler extends BasicHandler { * Tear down the thread-local contexts. */ private void tearDownContexts() { - // unset the transaction context TransactionContextManager tcm = TransactionContextManager.getInstance(); + + //delete temporary files + TransactionContext context = tcm.getTransactionContext(); + context.cleanAttachmentCache(); + + // unset the transaction context tcm.setTransactionContext(null); // unset the logging context @@ -250,4 +351,16 @@ public class AxisHandler extends BasicHandler { Logger.info(new LogMsg(msg.getMessage(messageId, parameters))); } + /** + * Utility function to issue an debug message to the log. + * + * @param messageId The ID of the message to log. + * @param parameters Additional message parameters. + */ + private static void debug(String messageId, Object[] parameters) { + MessageProvider msg = MessageProvider.getInstance(); + + Logger.debug(new LogMsg(msg.getMessage(messageId, parameters))); + } + } diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureCreationService.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureCreationService.java index 70dd3129c..2d548ea3a 100644 --- a/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureCreationService.java +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureCreationService.java @@ -16,6 +16,8 @@ import at.gv.egovernment.moa.spss.api.xmlbind.CreateXMLSignatureResponseBuilder; import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest; import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse; import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureCreationInvoker; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; import at.gv.egovernment.moa.util.Constants; import at.gv.egovernment.moa.util.StreamUtils; @@ -64,8 +66,10 @@ public class SignatureCreationService { CreateXMLSignatureRequest requestObj; CreateXMLSignatureResponse responseObj; + //since Axis (1.1 ff) has problem with namespaces we take the raw request stored by the Axishandler. + TransactionContext context = TransactionContextManager.getInstance().getTransactionContext(); // validate the request - reparsedReq = ServiceUtils.reparseRequest(request[0]); + reparsedReq = ServiceUtils.reparseRequest(context.getRequest()); // convert to API objects requestObj = requestParser.parse(reparsedReq); @@ -76,6 +80,9 @@ public class SignatureCreationService { // map back to XML response[0] = responseBuilder.build(responseObj).getDocumentElement(); + + // save response in transaction + context.setResponse(response[0]); } catch (MOAException e) { AxisFault fault = AxisFault.makeFault(e); diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureVerificationService.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureVerificationService.java index 1b15a197f..b335a6e23 100644 --- a/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureVerificationService.java +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureVerificationService.java @@ -1,8 +1,7 @@ package at.gv.egovernment.moa.spss.server.service; -import org.w3c.dom.Element; - import org.apache.axis.AxisFault; +import org.w3c.dom.Element; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.spss.MOAException; @@ -17,6 +16,8 @@ import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; import at.gv.egovernment.moa.spss.server.invoke.CMSSignatureVerificationInvoker; import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureVerificationInvoker; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; +import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; import at.gv.egovernment.moa.util.StreamUtils; /** @@ -52,8 +53,10 @@ public class SignatureVerificationService { VerifyCMSSignatureRequest requestObj; VerifyCMSSignatureResponse responseObj; + //since Axis (1.1 ff) has problem with namespaces we take the raw request stored by the Axishandler. + TransactionContext context = TransactionContextManager.getInstance().getTransactionContext(); // validate the request - reparsedReq = ServiceUtils.reparseRequest(request[0]); + reparsedReq = ServiceUtils.reparseRequest(context.getRequest()); // convert to API objects requestObj = requestParser.parse(reparsedReq); @@ -64,6 +67,9 @@ public class SignatureVerificationService { // map back to XML response[0] = responseBuilder.build(responseObj).getDocumentElement(); + // save response in transaction + context.setResponse(response[0]); + } catch (MOAException e) { AxisFault fault = AxisFault.makeFault(e); fault.setFaultDetail(new Element[] { e.toErrorResponse()}); @@ -107,8 +113,10 @@ public class SignatureVerificationService { VerifyXMLSignatureRequest requestObj; VerifyXMLSignatureResponse responseObj; + //since Axis (1.1 ff) has problem with namespaces we take the raw request stored by the Axishandler. + TransactionContext context = TransactionContextManager.getInstance().getTransactionContext(); // validate the request - reparsedReq = ServiceUtils.reparseRequest(request[0]); + reparsedReq = ServiceUtils.reparseRequest(context.getRequest()); // convert to API objects requestObj = requestParser.parse(reparsedReq); @@ -118,6 +126,9 @@ public class SignatureVerificationService { // map back to XML response[0] = responseBuilder.build(responseObj).getDocumentElement(); + + // save response in transaction + context.setResponse(response[0]); } catch (MOAException e) { AxisFault fault = AxisFault.makeFault(e); diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContext.java b/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContext.java index 407dbd4e9..774880d26 100644 --- a/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContext.java +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContext.java @@ -1,7 +1,20 @@ package at.gv.egovernment.moa.spss.server.transaction; +import iaik.ixsil.util.URI; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; import java.security.cert.X509Certificate; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Vector; +import java.util.Map.Entry; + +import org.apache.axis.attachments.ManagedMemoryDataSource; +import org.w3c.dom.Element; +import at.gv.egovernment.moa.spss.MOAApplicationException; import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; /** @@ -18,6 +31,12 @@ public class TransactionContext { private String transactionID = null; /** The name of the request. */ private String requestName = null; + /** The SOAP embedded request */ + private Element request; + /** The response which is to embed by SOAP */ + private Element response; + /** The map pointing to SOAP attachments needed by the request. */ + private HashMap attachments = null; /** The configuration to use throughout the request. */ private ConfigurationProvider configuration = null; @@ -39,6 +58,28 @@ public class TransactionContext { } /** + * Create a <code>TransactionContext</code> object. + * + * @param transactionID A unique ID for this <code>TransactionContext</code>. + * @param clientCertificate The client certificate chain. + * @param configuration The MOA configuration to use for this transaction. + * @param attachments to use for this transaction. + */ + public TransactionContext( + String transactionID, + X509Certificate[] clientCertificate, + ConfigurationProvider configuration, + Element request, + HashMap attachments) { + + this.transactionID = transactionID; + this.clientCertificate = clientCertificate; + this.configuration = configuration; + this.request = request; + this.attachments = attachments; + } + + /** * Returns the client certificate. * * @return The client certificate chain, if SSL client authentication has been @@ -78,6 +119,139 @@ public class TransactionContext { } /** + * Sets the the request. + * + * @param request The request to set. + */ + public void setRequest(Element request) { + this.request = request; + } + + /** + * Returns the request. + * + * @return The request. + */ + public Element getRequest() { + return request; + } + + /** + * Sets the the response. + * + * @param response The response to set. + */ + public void setResponse(Element response) { + this.response = response; + } + + /** + * Returns the response. + * + * @return The response. + */ + public Element getResponse() { + return response; + } + + /** + * Adds an attachment to the transactions list of SOAP attachments. + * + * @param referenceId Identification value for the SOAP attachment. + * @param contentType MIME type of the SOAP attachment. + * @param is Handle to the ManagedMemoryDataSource of the SOAP attachment. + */ + public void addAttachment(String referenceId, String contentType, ManagedMemoryDataSource is) { + if (this.attachments == null) this.attachments = new HashMap(); + Vector entry = new Vector(2); + entry.add(contentType); + entry.add(is); + this.attachments.put(referenceId, entry); + } + + /** + * Returns the ManagedMemoryDataSource to a specific SOAP attachment identified by referenceId. + * + * @param referenceId Identification value for the SOAP attachment. + */ + public ManagedMemoryDataSource getAttachment(String referenceId) { + if (attachments==null) { + return null; + } + Vector entry = (Vector) attachments.get(referenceId); + if (entry==null) { + return null; + } + //return (InputStream) ( ((ManagedMemoryDataSource)entry.get(1)).getInputStream()); + return (ManagedMemoryDataSource) entry.get(1); + } + + /** + * Returns the InputStream to a specific SOAP attachment identified by uri. + * + * @param uri Identification value for the SOAP attachment. + */ + public InputStream getAttachmentInputStream(URI uri) throws MOAApplicationException { + if (attachments==null) { + return null; + } + String referenceId = uri.getPath(); + Vector entry = (Vector) attachments.get(referenceId); + if (entry==null) { + return null; + } + + InputStream attachmentIs = null; + try { + attachmentIs = (InputStream) ( ((ManagedMemoryDataSource)entry.get(1)).getInputStream()); + } catch (IOException e) { + throw new MOAApplicationException("2208", new Object[] { uri }, e); + } + + return attachmentIs; + //If we would return the whole mmds: return (ManagedMemoryDataSource) entry.get(1); + } + + /** + * Returns the content type to a specific SOAP attachment identified by referenceId. + * + * @param referenceId Identification value for the SOAP attachment. + */ + public String getAttachmentContentType(String referenceId) { + Vector entry = (Vector) attachments.get(referenceId); + if (entry==null) { + return null; + } + return (String) entry.get(0); + } + + /** + * Delete the temporary attachment files. + */ +public void cleanAttachmentCache() { + if (null==attachments) { + return; + } + Iterator iterator = attachments.entrySet().iterator(); + while (iterator.hasNext()) { + Entry hmEntry = (Entry) iterator.next(); + Vector entry = (Vector)hmEntry.getValue(); + ManagedMemoryDataSource mmds = (ManagedMemoryDataSource)entry.get(1); + try { + if (mmds!=null) { + InputStream is = mmds.getInputStream(); + if (is!=null) is.close(); + File f = mmds.getDiskCacheFile(); + if (f!=null) f.delete(); + mmds.delete(); + } + } catch (IOException e) { + // ok to do nothing here + } + } + } + + /** * Returns the <code>ConfigurationProvider</code> associated with this * transaction. * @@ -86,5 +260,5 @@ public class TransactionContext { public ConfigurationProvider getConfiguration() { return configuration; } - + } |