cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andreas Veithen <>
Subject Re: Security token processing without SAAJ dependency
Date Sat, 09 Oct 2010 13:13:27 GMT
On Fri, Oct 8, 2010 at 18:13, Daniel Kulp <> wrote:
> On Friday 08 October 2010 7:23:55 am Andreas Veithen wrote:
>> The other alternative is to leave WSS4J unchanged and to let the SAAJ
>> implementation materialize the different parts of the object model on
>> demand. I have a working PoC that does this. It currently implements
>> an alternative SAAJInInterceptor that provides the following features:
>> * It always puts a SOAPMessage into the Message object, but the
>> SOAPPart (including the SOAP headers) is only instantiated on demand
>> when the SOAPMessage is accessed.
>> * The content of the SOAPBody is only materialized when is it actually
>> accessed. In addition, deferred parsing and building of the nodes is
>> supported for this part of the message. This means that WSS4J can
>> start processing the body of the message before it has been received
>> entirely.
>> * If the body has not been accessed, the StAX events are passed
>> through unchanged (e.g. to the interceptor that does the databinding
>> stuff). If the body has been accessed through the SAAJ API, then a
>> W3CDOMStreamReader is used to regenerate the StAX events.
>> All this is completely transparent for the interceptors further down the
>> chain.
> Hmm..  that's kind of cool.   More or less what Axiom should have been.  ;-)
>> Of course, this is impossible to achieve using a standard SAAJ
>> implementation. Therefore the interceptor uses an alternative SAAJ
>> implementation which I have written as part of a larger project called
>> DDOM [1].
> And I think this is where the issues may start popping up, but definitely
> resolvable.  If you look at the CXF survey, one of the MAJOR "areas of
> improvement" for CXF was too many external dependencies.   I'm kind of
> reluctant to add more "required" deps.   Thus, the security stuff would need
> to work with the default SAAJ impl (in particular, the one built into the
> JDK), but I could definitely see making something like this as an optional
> "performance enhancment" type thing.  Ideally, the existing SAAJ interceptor
> would be smart enough to checkt he SAAJ impl being used and do the smart thing
> depending on what it sees.

What about the following solution:
* Introduce a new SAAJManager interface that encapsulates the SAAJ
handling stuff.
* Create a default implementation based on the code currently
contained in the standard SAAJ interceptors.
* Refactor SAAJInInterceptor and SAAJOutInterceptor to look up the
SAAJManager using Bus#getExtension. If none is found, fall back to the
default implementation.
* Maybe also refactor the WSS4J interceptors to use SAAJManager
instead of instantiating SAAJ(In|Out)Interceptor.
* My ddom-cxf stuff would then provide an alternative SAAJManager
implementation and automatically register that as a bus extension.

> If the DDOM stuff we need can be squashed/shaded
> into a single jar that is just a drop in replacement of saaj-impl, that
> concern could also be aleviated quite a bit as well.

Yes, I was also thinking the same. There are a couple of other reasons
why this is a good idea:
* The DDOM project is split into a multitude of smaller modules, so
that for every use case, you only get the stuff that is really needed
(e.g. some modules depend on the Axiom APIs, but you don't want that
as a transitive dependency for the CXF stuff ;-). This works well when
Maven is used, but of course it's a pain for users who use other
* The code in the CXF stuff is (currently) tightly coupled to some
internal DDOM APIs that are likely to change over time. Thus,
packaging all the required stuff into a single JAR and shade it makes
sense because it avoids conflicts caused by incompatible versions of
DDOM modules.

> That said, the callback method added to WSS4J has an additional use case that
> Sergey and I have been noodling on outside of SOAP.    One thing we're trying
> to figure out how to do is leverage some of the WS-SecPol support to provide
> message level security for XML REST payloads.  With the callback, we MAY be
> able to have separate XML sources for the security header and the actual
> payload (think separate MIME containers) where we feed the security header
> into WSS4J, and it calls back out to us to load the other parts as/if needed.
> Very early in the "noodling in our heads" stages.    :-)

The DDOM solution here would simply be to compose the equivalent SOAP
message and pass that to WSS4J. This would mean creating a skeleton
SOAP message and adding the source objects for the header and body
parts to that skeleton. It is definitely possible to defer the
expansion of these parts (and even the lookup of the corresponding
MIME parts from the message) until the very last moment. This is
conceptually similar to your solution except that the callbacks are
invoked by the DOM/SAAJ implementation instead of WSS4J. This could
have some advantages:

* The scope of WSS4J would remain strictly limited to WS-Security and
no API changes are needed.
* If I understand your idea correctly, then conceptually you are
defining a mapping between REST style requests/responses and SOAP
messages conforming to WS-Security. With DDOM, the code that
implements this would simply be a direct transcription of these
mapping rules (plus of course some glue code).

>> The implementation is still incomplete, but to give you an
>> idea about its current status:
>> * The underlying DOM implementation successfully passes the W3C DOM1
>> and DOM2 test suites, except for features not relevant to SOAP
>> processing (such as DTD information, entity references, etc.).
> That's good.   DTD handling with Stax really sucks.   Good luck with that.
> ;-)

It's definitely not possible to implement all JAXP/DOM features by
relying on a standard StAX implementation as the underlying parser. If
there is a requirement for full JAXP/DOM support, then probably the
better option would be to use Xerces XNI (which also has some kind of
pull parsing support).

>> It also
>> successfully passes the most important parts of the DOM3 test suite.
>> * When configured as SAAJ implementation in the CXF build (without the
>> custom SAAJInInterceptor), it passes all unit tests up to the systests
>> (It seems that this is primarily due to the fact that some of the
>> systests use SAAJ to compose test messages).
> Likely yes.   Do you have a feeling as to whether  those are issues in the CXF
> tests or issues with DDOM?

These are issues in DDOM. They are simply due to the fact that many
SAAJ methods in DDOM are still unimplemented ;-). What I wanted to say
here is that there is enough stuff in DDOM's SAAJ implementation to
play nicely with CXF's own code. Of course, once the SOAPMessage is
exposed to user code through a JAX-WS handler or provider endpoint,
this is no longer enough. As I said, for the moment it's a PoC.

> I see in the code that it doesn't support attachments either.   That would be
> required for the JAX-WS TCK.  (and likely for some of the systests as well)
> That said, those should be fairly easy to handle since you have the
> SoapMessage.     The DDOM version could be MUCH more efficient by not
> buffering the attachments unless they really are accessed.    One of my
> "issues" with the JAX-WS handlers is they require us to stop streaming
> EVERYTHING and buffer it, even if the only thing the  handler does is:
> System.out.println("Hello World!");
> this could be a huge help with that.

The SAAJ stuff in DDOM is actually split into two parts:
* The part that implements the SAAJ object model. This contains the
code that extends DOM and also some partial implementations of
SOAPMessage and SOAPPart. On the other hand, it doesn't contain any
MIME parsing or attachment management logic.
* The part that provides the SAAJ factories and thus the complete SAAJ
implementation. Of course this part depends on the first part and will
eventually contain the MIME parsing logic to satisfy the requirements
of the SAAJ spec.

When running the CXF test suites against DDOM I use both parts as a
drop-in replacement for Sun's saaj-impl. On the other hand, the custom
SAAJInInterceptor only uses the first part. This means that the
SOAPMessage implementation is not the same as the one that would be
created by MessageFactory. Instead it uses an implementation that is
basically a wrapper around a org.apache.cxf.binding.soap.SoapMessage
object. This can be seen here:

The idea is that the methods that are used to manage attachments (and
that are currently unimplemented) would all delegate to the
corresponding CXF APIs. This means that all optimizations done by CXF
would also work when accessing the attachments through SAAJ. Since
SAAJ exposes attachments via iterators, the only case were all
attachments are buffered would be a call to countAttachments...

BTW, I'm interested in references to test cases, issue reports or
mailing list discussions that describe use cases that could be
optimized using this custom SAAJ implementation.

>> * When configured as DOM implementation in the WSS4J build, it passes
>> all unit tests except some of the tests related to SAML (because
>> OpenSAML expects to get schema support from the DOM implementation
>> available though JAXP).
>> * I tested the implementation successfully with the scenarios
>> developed by Dennis Sosnoski [2] (both by simply configuring DDOM as
>> SAAJ implementation as well as using my alternative
>> SAAJInInterceptor).
>> The code for the custom SAAJInInterceptor is available here:
>> Note that besides the limitations mentioned above, there are currently
>> some features missing in this SAAJInInterceptor implementation that
>> needs to be mentioned, namely processing of SOAP faults and the
>> ability to access attachments through the SAAJ API.
> Ah.  Yep.    Didn't read far enough.  :-)
>> Some preconfigured CXF (2.3.0) clients and services (containing code
>> from Dennis' article) are available here:
>> Note that for the moment, they still use Sun's SAAJ implementation for
>> outgoing messages. Therefore the interesting things happen in the
>> response processing on the client side.
>> I did some initial performance tests with the scenarios developed by
>> Dennis and the results suggest that my SAAJ implementation performs
>> slightly better than the one from Sun, resulting in a few percent
>> points improvement in the "sign" and "signencr" scenarios. Note that
>> the features of the custom SAAJInInterceptor are not relevant here
>> because the body is accessed anyway in these scenarios. I think that
>> the improvement primarily results from a reduced memory footprint.
>> Maybe Dennis could volunteer as an "independent" performance tester to
>> confirm this?
>> BTW, while doing some profiling, I noticed that in the "signencr"
>> scenario, CXF suffers from a flaw in Santuario's code, namely
>> which does some highly inefficient stuff. I think that by doing that
>> part of the processing in a smarter way, it may be possible to perform
>> better than Metro in the small-response case and to increase the gap
>> with respect to Metro in the large-response case.
> Yea.  Colm is aware of a few places in both WSS4J and Santuario that could use
> some work.   He hasn't had time to work on it yet, but, if all goes well,
> he'll have some time soon.  ;-)
> Dan
>> Andreas
>> PS: As noted between the lines by Daniel, optimizing the security
>> processing for outgoing messages is much more difficult, at least in
>> CXF. In principle, the Axis2 architecture would allow to achieve this
>> more easily, but before this can be leveraged, there are some other
>> performance issues in Axis2/Rampart that need to be fixed...
>> [1]
>> [2]
> --
> Daniel Kulp

View raw message