I’ve been doing a bit of work for a client that centres around SAML & XML Signatures over a SOAP transport. I’ve done plenty of work in the SAML space before (and XML Security for that matter), but the web services angle is new.
Anyways, it gave me a chance to look at the (surprisingly slim) SAML Java landscape again to see what’s hip and happening. I’ve developed stuff with Verisign TSIK (which has interestingly been donated to Apache recently… but without the SAML stuff), but these days I’m pretty happy with opensaml. I’ve found it’s very accurate to the SAML spec, and the library is very productive to work with. Only neg is the use of a special (later?) JAXP dependency meaning you have to do funny business with /jre/lib/endorsed overrides for the javax.xml.* replacements. Under the covers uses Apache XML Security for the digital signature stuff which seems to work just great.
I thought it was all going to be so simple… until I took a look at how the SOAP DOM implementation integrated with what the XML Security library wanted out of it.
XML Security goes through a process called Canonicalisation (c14n) on the XML before calculating hashes and whatnot. That process takes into account namespaces that are in place for the elements being signed and handles the various ways the same piece of xml can be represented. For example, an element which is represented as zz:myelement xmlns:zz="http://xxx"
could just as validly be stored as myelement xmlns="http://xxx"
and the same signature will still hold. Throw a single extra character of whitespace into the body of the tags, or insert any new namespaces into the picture, and your hosed…
Which is where my problems began. The implementation of the DOM interfaces in the underlying SOAP library was… well.. suboptimal. Some of the namespacing on the elements and attributes was just broken. And as for the SOAP API, well, I found myself actually liking and respecting DOM after going through the pain of creating SOAP Names, and then associated Elements and then trying to append them to various places… and finding out they’re not really children of the element you just added them to until you call update() on the message context…
After blowing a ton of time working out what was all bad, I finally worked out a strategy. Write out the SOAP message to a stream, feed that stream into a real DOM document, calculate your signature, add your nodes, then tranform the resulting DOM back into a SOAP message. Voila! Valid signatures and valid SOAP.
And don’t even get me started on JAX RPC fault handling… that’s for another day. But it has taught me that not all DOMs are created equal. You’ve been warned…
But huge props to the opensaml and Apache XML Security guys… both first class offerings.