Hi,
I'm quite new to Axis so forgive me if ask something stupid.
We are developing a middleware application which already has numerous north-
and southbound interfaces towards other software components. We already have
a solution for SOAP communication (it's based on a simple embedded HTTP
server and some predefined XML snippets) which has worked so far, but we are
facing a new use case now which may force us to use a new approach (our
northbound integration is too specific especially in the field of security).
There are some constrains and criterias concerning deployment,configuration
and throughput that must be fulfilled by the new solution.
Currently our software consist of several standalone Java processes
communicating using an internal CORBA interface (no application server) and
all configuration is done centrally through one property file manually or
using our configuration GUI; our project leader wants to keep things this
way, this is why I'm searching a solution that is fully embeddable and can
be fully configured and manipulated programmatically.
In the last few days I was investigating the possibility of using Axis2 and
more importantly its Rampart module embedded into our POJO project. At first
I've tried to find similar use cases on the web but all I've managed to
find were some cases where Axis was embedded into a web application running
on some kind of an application server and some examples about the use of the
SimpleHTTPServer included in Axis2. Using these examples and the
SimpleHTTPServer I was able to deploy a simple POJO class (the Echo example
service found on numerous web pages) as a service and engage the Rampart
module (only a Timestamp is required in the request and the response) on it
fully programmatically but had some exceptions when the service was exposed
and I need some tips with these problems. I'm not sure if anyone has done
something similar but thanks for any help. So the details:
- I'm using the SimpleHTTPServer to host my test service which is a POJO
service
- Rampart module is engaged using the classes in the Rampart distribution by
using an instance of the AxisnModule class with a programmatic configuration
based on the contents of the Rampart module's deployment descriptor
*1.* On the first tries when I invoked the deployed service with Rampart
engaged on the server, my requests were sucessful regardless of the missing
security header (only a timestamp) of the request. To find out the cause
I've debugged the program flow during request processing and I've found out
that this behaviour was caused during the execution of Rapmpart's
WSDoAllReceiver class. More concretely by the Object keyed with
WSSHandlerConstants.INFLOW_SECURITY_SERVER (InflowSecurity-server) missing
from either the options or the message context and similarly by the Object
keyed with WSSHandlerConstants.INFLOW_SECURITY_CLIENT
(InflowSecurity-client) missing from the same places. The relevant code in
the WSDoAllReceiver class starts at line 119, you can see that the whole
security functions are bypassed when the values retrieved by the ywo keys
are nulls. I assume both of these keys are populated somehow in a normal
deployment environment, but in my case they weren't as I've used only the
WSSHandlerConstants.INFLOW_SECURITY (InflowSecurity) and
WSSHandlerConstants.OUTFLOW_SECURITY (OutflowSecurity) keys to configure
security on my service. My question is how are these missing keys poulated
during normal deployment, what are their default values? I've currenlty
managed to bypass this problem by putting instances of the Object class into
the AxisConfiguration context using the two keys.
*2.* Using the dummy INFLOW_SECURITY_SERVER and INFLOW_SECURITY_CLIENT
objects I was able to come a bit further, but found a new problem for
myself. Now my service invocations are failing as they should but the
correct soap message is not returned to the client. I see the correct
exception in the server logs (org.apache.axis2.AxisFault: WSDoAllReceiver:
Incoming message does not contain required Security header) but directly
after that I get an other exception and no result is returned to the client.
I get the following exception:
WARN [HttpConnection-8080-1] - Error in extracting message properties
org.apache.axis2.AxisFault: Error in extracting message properties
at
org.apache.rampart.handler.RampartSender.invoke(RampartSender.java:70)
at org.apache.axis2.engine.Phase.invoke(Phase.java:317)
at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:264)
at org.apache.axis2.engine.AxisEngine.sendFault(AxisEngine.java:520)
at
org.apache.axis2.transport.http.server.AxisHttpService.doService(AxisHttpService.java:320)
at
org.apache.axis2.transport.http.server.AxisHttpService.handleRequest(AxisHttpService.java:187)
at
org.apache.axis2.transport.http.server.HttpServiceProcessor.run(HttpServiceProcessor.java:82)
at
edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1061)
at
edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:575)
at java.lang.Thread.run(Thread.java:619)
Caused by: org.apache.rampart.RampartException: Error in extracting message
properties
at
org.apache.rampart.RampartMessageData.<init>(RampartMessageData.java:322)
at org.apache.rampart.MessageBuilder.build(MessageBuilder.java:61)
at
org.apache.rampart.handler.RampartSender.invoke(RampartSender.java:64)
... 9 more
Caused by: org.apache.ws.security.WSSecurityException: Error in converting
SOAP Envelope to Document; nested exception is:
org.apache.axiom.soap.SOAPProcessingException: Only Characters are
allowed here
at
org.apache.rampart.util.Axis2Util.getDocumentFromSOAPEnvelope(Axis2Util.java:161)
at
org.apache.rampart.RampartMessageData.<init>(RampartMessageData.java:158)
... 11 more
Caused by: org.apache.axiom.soap.SOAPProcessingException: Only Characters
are allowed here
at
org.apache.axiom.soap.impl.builder.SOAP11BuilderHelper.processText(SOAP11BuilderHelper.java:151)
at
org.apache.axiom.soap.impl.builder.SOAP11BuilderHelper.handleEvent(SOAP11BuilderHelper.java:63)
at
org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.constructNode(StAXSOAPModelBuilder.java:374)
at
org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.createOMElement(StAXSOAPModelBuilder.java:219)
at
org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.createNextOMElement(StAXSOAPModelBuilder.java:191)
at
org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:172)
at org.apache.axiom.om.impl.dom.NodeImpl.build(NodeImpl.java:449)
at
org.apache.axiom.om.impl.dom.DocumentImpl.build(DocumentImpl.java:488)
at
org.apache.rampart.util.Axis2Util.getDocumentFromSOAPEnvelope(Axis2Util.java:134)
... 12 more
Debugging the Rampart code I've found a posible cause but I'm not sure what
to do about this one. I think the root cause for this is that the
AxisService attribute is not copied when the FaultContext gets created from
the original message context so its value will remain null. When the Rampart
sender creates the RampartMessageData this null value causes a null pointer
exception at line 308 of the constructor of the RampartMessageData
class (*this.customClassLoader
= msgCtx.getAxisService().getClassLoader();*). This may mean some
inconsistency in this class because there is already a null value check for
the value of the AxisService with a TODO comment indicating that there can
be cases where the AxisService is null (the relevant code starts at line 177
of RampartMessageData). I'm not sure if this can be bypassed at all with
some changes in my programmatic deployment, but I would be very happy if
someone had some idea how to solve this.
This got a bit lengthy and it's possible that my whole idea is wrong; feel
free to tell me so, at least I won't waste more time with something
impossible.
Best regards,
Csaba