WSO2 ESB WS-Security with MTOM - ws-security

Having WSO2 ESB 4.9.0, is it possible to enable the client WS-Security, set-up a policy for the endpoint, where the external (backend) service returns the MTOM attachment?
requirement: the external backend service requires the request to be signed and returns (optionally) MTOM response, which is not signed (plain).
As soon the Rampart module is engaged and an inbound policy is in force, the response doesn't get through a simple proxy with following exception:
Caused by: org.apache.ws.security.WSSecurityException: Error in converting SOAP Envelope to Document; nested exception is:
org.apache.axiom.om.OMException: javax.xml.stream.XMLStreamException: Expected xop:Include as the sole child of an element information item (see section 3.2 of http://www.w3.org/TR/xop10/)
at org.apache.rampart.util.Axis2Util.getDocumentFromSOAPEnvelope(Axis2Util.java:149)
at org.apache.rampart.RampartMessageData.<init>(RampartMessageData.java:268)
... 11 more
Caused by: org.apache.axiom.om.OMException: javax.xml.stream.XMLStreamException: Expected xop:Include as the sole child of an element information item (see section 3.2 of http://www.w3.org/TR/xop10/)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:296)
at org.apache.axiom.om.impl.llom.OMSerializableImpl.build(OMSerializableImpl.java:78)
at org.apache.axiom.om.impl.llom.OMElementImpl.build(OMElementImpl.java:722)
at org.apache.rampart.util.Axis2Util.getDocumentFromSOAPEnvelope(Axis2Util.java:84)
... 12 more
Caused by: javax.xml.stream.XMLStreamException: Expected xop:Include as the sole child of an element information item (see section 3.2 of http://www.w3.org/TR/xop10/)
at org.apache.axiom.util.stax.xop.XOPDecodingStreamReader.next(XOPDecodingStreamReader.java:187)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.parserNext(StAXOMBuilder.java:681)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:214)
... 15 more
However - there is the Include element:
<inc:Include href="cid:30545cee-7014-4149-8b77-7014e3e12a8c#xxxxxxx" xmlns:inc="http://www.w3.org/2004/08/xop/include"/>
Trying to test the service locally (creating a mockup service similar to the external service) I've got an exception:
Caused by: org.apache.axiom.om.OMException: Part content ID cannot be blank for non root MIME parts
at org.apache.axiom.attachments.Attachments.getNextPartDataHandler(Attachments.java:648)
at org.apache.axiom.attachments.Attachments.getDataHandler(Attachments.java:350)
which I assume is related to the issue https://wso2.org/jira/browse/ESBJAVA-3585. Is it related or I have wrong mockup service? Does MTOM works with security policy enabled?

Seems there are two issues involved:
Caused by: javax.xml.stream.XMLStreamException: Expected xop:Include as the sole child of an element information item (see section 3.2 of http://www.w3.org/TR/xop10/)
This is caused by the "pretty print" feature of the backend service. Axis 2 enforces the specification strictly, where the xop:Include element must be the sole and only child, therefore no whitespaces are allowed.
org.apache.axiom.om.OMException: Part content ID cannot be blank for non root MIME parts
This seems to be a bug, not yet solved at this time.
https://wso2.org/jira/browse/ESBJAVA-3585
Workaround could be change the message type to text/xml (effectively inserting base64 payload to the XML element), good for small/reasonable attachment sizes.
If the attachments can be bigger or the load is high, it is to be considered to store the attachment as a file and pass back only the file name.

Related

SOAP Web Service Client error, While consuming the service

I am getting this error while using SOAP web service client with axis 1. I had created stub from the wsdl file and tried to consume it then I got this error. wsdl is given to me by someone else.
error in msg parsing: xml was empty, did't parse!
below is the error message and stack trace for the same. Anyone can help.?
In order to fix the javax.activation.DataHandler issue you must add the JavaBeans Activation Framework activation.jar in your classpath.
In order to fix the javax.mail.internet.mimeMultipart issue you must add the Java Mail API mail.jar in your classpath.
The warning messages printed in your console shows that the above jars are not in the classpath.
There are several common reasons to receive the message:
error in msg parsing: xml was empty, did't parse!
The most obvious is that no message was sent. If you have some way of inspecting your transport channel, that would be worth looking at.
Also, the xml message could have been sent in an unexpected character set, e.g. A header declares it to be "Utf-8" but it is really "Win-1252", sometimes you can get away with that if you only use 7-bit ASCII characters, but anything in the 8-bit plane will cause it to bomb.
Also, the xml message could have had a byte order mark unexpectedly inserted at the beginning of the message.
Also, the xml message might not have the document declaration ( starting in the first byte of the message, that violates the specification, and often causes parsers to puke and claim that no message was found.
All things considered with this error message, the parser was not able to find a valid xml message that it could parse, so it didn't. You need to grab the data on the transport channel and figure out what exactly is wrong to resolve the issue.

REST API: HTML generic error response for Invalid JSON

Service X host REST APIs and is behind service Y.
Clients -> Y -> X
For invalid JSON, service Y responds back with HTML error (shown below). Service X does not have control over Y.
<html>
<head><title>400 Bad Request</title></head>
<center><h1>400 Bad Request</h1></center>
</body>
</html>
For all other type of errors, X responds back with appropriate HTTP response code and an Error JSON (Following format).
{
"errorCode": "InvalidXXX",
"message": ""
}
I am trying to check if there exists any RFC around REST API error response standards?
Is there a security risk if service returns an error response with details mentioning the JSON is invalid?
I am trying to understand whether it will be fine for us to document this special case as part of integration guide for clients.
I am trying to check if there exists any RFC around REST API error response standards?
REST is an architectural style defined by Fielding in the chapter 5 of his dissertation and it says nothing about the response format for errors.
I assume you are doing REST over HTTP, so I advise you to choose the most suitable status code for each situation. Status codes are meant to indicate the result of the server's attempt to understand and satisfy the client's request.
Status codes are sometimes not sufficient to convey enough information about an error to be helpful and some details sent in the payload can help the client to understand what caused the error.
If you are looking for a standard from IETF to report errors, the closest you'll find is probably the RFC 7807. This specification defines simple JSON and XML document formats to report errors to the client, along with the application/problem+json and application/problem+xml media types.
Is there a security risk if service returns an error response with details mentioning the JSON is invalid?
When it's a client error, it makes sense to inform the client on what's wrong, so they can fix it and perform a new request. You shouldn't, however, leak any stack trace or internal details that could be exploited by a malicious user.

Smack throws NullPointerException in Roster's presence listener

I'm using Smack with android chatting applications and recently I have updated Smack to version to 4.3.0 and getting some error in fabric. It is a NullPointerException inside of Smack:
Fatal Exception: java.lang.NullPointerException
Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
java.util.concurrent.ConcurrentHashMap.get (ConcurrentHashMap.java:772)
org.jivesoftware.smack.roster.Roster.getPresencesInternal (Roster.java:374)
org.jivesoftware.smack.roster.Roster.getOrCreatePresencesInternal (Roster.java:388)
org.jivesoftware.smack.roster.Roster.access$1100 (Roster.java:94)
org.jivesoftware.smack.roster.Roster$PresencePacketListener$1.run (Roster.java:1502)
org.jivesoftware.smack.AsyncButOrdered$Handler.run (AsyncButOrdered.java:121)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1113)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:588)
java.lang.Thread.run (Thread.java:818)
"Use the source, Luke (and study the relevant open standard)" Obi-Wan Kenobi
Smack is open soure, so let us look at the source: One interesting part is
org.jivesoftware.smack.roster.Roster.getPresencesInternal (Roster.java:374)
which reads
Map<Resourcepart, Presence> entityPresences = presenceMap.get(entity);
Source: https://github.com/igniterealtime/Smack/blob/4.3.0/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java#L374
We also find that presenceMap is declared as follows
private final Map<BareJid, Map<Resourcepart, Presence>> presenceMap = new ConcurrentHashMap<>();
Source: https://github.com/igniterealtime/Smack/blob/4.3.0/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java#L168
So it is a ConcurrentHashMap, which matches with the stacktrace. It is obvous that entity above is null, which is the cause of the NullPointerException.
Now we need to walk the call stack up (or down, depening on your point of view), to determine where entity origins from. Here the interesting part is
org.jivesoftware.smack.roster.Roster$PresencePacketListener$1.run (Roster.java:1502)
which reads
userPresences = getOrCreatePresencesInternal(key);
Source: https://github.com/igniterealtime/Smack/blob/4.3.0/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java#L1562
so enitty is key here. Which is declare and define just a few lines above
final BareJid key = from != null ? from.asBareJid() : null;
Source: https://github.com/igniterealtime/Smack/blob/4.3.0/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java#L1562
So in case from is null, keywill also be null. Which later causes theNullPointerException. Looking at the code, we find that this is caused by a presence XMPP stanza without a from` attribute set.
The question is now if those stanzas are legal in XMPP. To determine that, we need to have a look at the specification. The relevant part is [RFC 6120 § 8.1.2.1 4.],1, which states
When the server generates a stanza from the server for delivery
to the client on behalf of the account of the connected client
(e.g., in the context of data storage services provided by the
server on behalf of the client), the stanza MUST either (a) not
include a 'from' attribute or (b) include a 'from' attribute
whose value is the account's bare JID (localpart#domainpart).
So a missing 'from' attribute is generally allowed and is equal to the "account's bare JID".
Now the question is: Are there any presence stanzas specified send from the server to the client which do not have a 'from' attribute? I could not find any while reading the related RFC 6121. And I am not aware when this should ever happen (I possibly could be missing someting). But right now this appears to be a bug in the entity which creates those presence stanzas, which is the used XMPP server implementation.
(What XMPP server implementation do you use?).

LoadRunner GWT to XML Conversion

We have an application which uses GWT for the communication. I have enabled DFE (In Loadrunner - Vugen) and selected GWT as the option and provided application .WAR file as the input to extract All Application related .jar files.
Recorded the scenario flow, and i see all the requests are converted from GWT to XML format. But then when i reply the test script i am having errors as DFE is not able to convert the HTTP response from GWT fromat to XML format.
What are the other options that we can try to resolve this error and convert to XML format? And is there a way that we can supress the Loadrunner error message, so that it will proceed with the next steps instead of failure?
Do we need any additional .jars for converting HTTP responses?
HTTP Response (In GWT Format): //OK[[],0,5]
Error Message:
Action.c(93): Error -27040: Data Format Extension: Extension: GWT - ERROR
[GWT_DFE] - Failed to parse response:
java.lang.ArrayIndexOutOfBoundsException: -1
java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(ArrayList.java:403) ~[?:1.8.0-internal]
at java.util.ArrayList.get(ArrayList.java:416) ~[?:1.8.0-internal]
atcom.gdevelop.gwt.syncrpc.SyncClientSerializationStreamReader.readInt(SyncClientSerializationStreamReader.java:450) ~[SyncProxy.jar:?]
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:46) ~[gwt-servlet-2.0.4.jar:?]
at com.hp.dfe.GWT_DFE.deserializeResponseToXML(GWT_DFE.java:462) [classes/:?]
at com.hp.dfe.GWT_DFE.decode(GWT_DFE.java:704) [classes/:?]
at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0-internal]
at java.lang.reflect.Method.invoke(Method.java:483) ~[?:1.8.0-internal]
at com.hp.dfe.GWT_DFE_DYNAMICALLY_REFLECTED.doOperation(GWT_DFE_DYNAMICALLY_REFLECTED.java:70) [classes/:?]
at com.hp.dfe.GWT_DFE_DYNAMICALLY_REFLECTED.decode(GWT_DFE_DYNAMICALLY_REFLECTED.java:60) [classes/:?]
at com.hp.dfe.GWT_DFE_LAUNCHER.decode(GWT_DFE_LAUNCHER.java:456) [classes/:?]
[MsgId: MERR-27040]
Action.c(93): Error -27040: Data Format Extension: Extension: GWT - ERROR [GWT_DFE] - failed to read as a response
Øp–ñ´Ò
[MsgId: MERR-27040]
Thanks.
That looks like an empty (void return type) response for an old version of gwt - the status was success (//OK), there are no flags set (0), the version is pretty old (5), and the array of strings is empty, since there is no other data to send back. Sounds instead to me like your GWT_DFE class is expecting that all responses always have a value, or that something else is very wrong in how they are handling the response (perhaps they can't handle the old version well? I'd be just blindly guessing at this point, that code isn't publicly available).
If you have a RemoteService method like void sendMessage(SomeObject object), there may be no need for any return type other than the onSuccess response itself. The matching async interface would then have AsyncCallback<Void>, and would not get a return value.

Apache Camel throttling with a SOAP endpoint -> TransformerException

We have an Apache Camel application providing SOAP service. The "initial route" starts from a Apache CFX -provided endpoint.
We need a simple mechanism to prevent the messages from being handled "too fast" (and don't have massive scalability needs).
Thus we ended up trying Throttler. Now, the problem is that after adding throttle to our route, something goes wrong.
The initial route, somewhat cleaned:
from("cxf:bean:sapEndpoint").routeId(SOAP_ENDPOINT)
.throttle(1)
.onException(Exception.class)
.to("direct:emailFaultNotification").handled(false)
.end()
.transacted(joinJpaTx)
.to(xsltRemoveEmptyElements) // Cleaning done with XSLT endpoint
.to("direct:inboundWorkOrderXml"); // Forward to actual processing
// direct:inboundWorkOrderXml contains various validation, persistance & response
Error in our log:
2013-02-18 16:50:16,257 [tp1636587648-50] ERROR DefaultErrorHandler - Failed delivery for exchangeId: ID-...-4. Exhausted after delivery attempt: 1 caught: javax.xml.transform.TransformerException: javax.xml.transform.TransformerException: com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Content is not allowed in prolog.
javax.xml.transform.TransformerException: javax.xml.transform.TransformerException: com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Content is not allowed in prolog.
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:735)[:1.6.0_37]
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:336)[:1.6.0_37]
at org.apache.camel.builder.xml.XsltBuilder.process(XsltBuilder.java:98)[camel-core-2.7.0.jar:2.7.0]
at org.apache.camel.impl.ProcessorEndpoint.onExchange(ProcessorEndpoint.java:102)[camel-core-2.7.0.jar:2.7.0]
at org.apache.camel.impl.ProcessorEndpoint$1.process(ProcessorEndpoint.java:72)[camel-core-2.7.0.jar:2.7.0]
...
I suppose that throttler doesn't work straight the way I supposed.
It seems that with throttling enabled, the XSLT endpoint receives empty or invalid XML? Without throttle definition everything works fine. With short try, the message body still seems to contain XML string?
Some ideas?
When using Camel error handling for redelivery then mind about streaming payloads. See about stream-caching at: http://camel.apache.org/stream-caching.html
There is also a tip in the top of the Camel CXF documentation page at: http://camel.apache.org/cxf about this
Finally the solution was more simple than I thought. Instead of using throttle in the route starting from "cxf:bean:sapEndpoint", I added throttle to route handling "direct:inboundWorkOrderXml".
Don't know the exact reason, could be somehow related to that some parts of throttle functionality might vary related on the from-endpoint of the route. (So problem with cxf-endpoint not encountered with direct-endpoint)