Tuesday, February 21, 2017

WS-Security with MTOM support in Apache CXF 3.2.0

Getting WS-Security to work with MTOM-enabled web services has been a long-standing feature request in Apache CXF. A couple of years ago, support was added to CXF and WSS4J to store raw cipher data in message attachments when MTOM is enabled, to avoid the cost of BASE-64 encoding the bytes and inlining them in the message. However, CXF did not support signing/encrypting content that contained xop:Include Elements (properly). In this case, just the references were signed/encrypted and not the attachments themselves (the user was alerted to this via a warning log). From Apache CXF 3.2.0, WS-Security with MTOM will be properly supported, something we will cover in this post.

1) Securing an MTOM-enabled message with WS-Security

Let's look at the outbound case first. There is a new configuration option in WSS4J 2.2.0:
  • expandXOPInclude: Whether to search for and expand xop:Include Elements for encryption and signature (on the outbound side). This means that the referenced bytes are encrypted/signed, and not just the references. The default is false on the outbound side in WSS4J.
CXF will set this configuration option to "true" automatically for both the "action" based and WS-SecurityPolicy based approaches if MTOM is enabled. Note that this configuration option also applies on the inbound side with slightly different semantics (see below).

The way this configuration option works is that it scans all children of all message elements to be signed/encrypted, and inlines any xop:Include bytes that it finds before signature/encryption. For the encryption case, if the "storeBytesInAttachment" configuration option is set to true (false in WSS4J, true by default in CXF if MTOM is enabled), the encrypted bytes are then stored in a message attachment. For signature, the original Element is retained and the inlined version is discarded and not included in the request, meaning that the signed bytes are not modified as a message attachment.

2) Validating an MTOM-enabled message with WS-Security

On the inbound side, the "expandXOPInclude" configuration option also applies:
  • expandXOPInclude: Whether to search for and expand xop:Include Elements prior in signed elements to signature verification. The default is "true". Note that this replaces the previous "expandXOPIncludeForSignature" configuration option prior to WSS4J 2.2.0.
CXF overrides this default behaviour by only setting "expandXOPInclude" to "true" on the inbound side if MTOM is enabled. So to summarize, if you wish to support WS-Security with MTOM in CXF from the (future) 3.2.0 release, you don't need to set any configuration option by default to get it to properly sign and encrypt the message bytes. CXF will take care of setting everything up for you.


  1. Hi,
    how can I use the "expandXOPInclude" configuration with WS-SecurityPolicy?
    It seems that PolicyBasedWSS4JStaxOutInterceptor/PolicyBasedWSS4JOutInterceptor does not use the optiion while WSS4JOutInterceptor does.

    Currently we have issues in a migration project. One server uses CXF 3.1.x (and stys on this version for some months) while the other server is migrated to CXF 3.2.7.
    Now we get "WSSecurityException: The signature or decryption was invalid" for the services that use MTOM attachments and signatures that are configured with WS-SecurityPolicy directrly in the WSDL.

  2. I've added a new configuration tag for CXF 3.3.3 for WS-SecurityPolicy - "ws-security.expand.xop.include". See here: https://cwiki.apache.org/confluence/display/CXF20DOC/WS-SecurityPolicy

  3. Thank you very much.
    Now I'll try to convince the support of our appeserver vendor to backport it to 3.2.x and into the product