The behavior of Rampart when doing encryption of any attachments such MTOM is to Base64 encode the attachment, place it in the body and continue encrypting it as any other SOAP body payload. There are two simple solutions for this.
1. Use SSL
2. Write the WS-Security policy to exclude attachments from being encrypted.
For some people these two might be not be a solution. In this blog post I am trying to provide an alternative for them.
There is a configuration in Rampart to say, optimize a particular part in the soap message that is denoted using XPath. This optimization runs after any encryption. Using this you can direct Rampart to optimize the data that you just encrypted.
E.g. if you have a binary payload in your SOAP body and you want to encrypt it and send it as an attachment:
Your WS-SecurityPolicy would contain the following which says to encrypt the entire SOAP body.
<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"> <sp:Body/> </sp:EncryptedParts>
And your Rampart configuration would have the following which says to optimize the binary content found at the specified XPath location.
<rampart:optimizeParts> <rampart:expressions> <rampart:expression>//xenc:EncryptedData/xenc:CipherData/xenc:CipherValue</rampart:expression> </rampart:expressions> <rampart:namespaces> <rampart:namespace prefix="xenc" uri="http://www.w3.org/2001/04/xmlenc#"></rampart:namespace> </rampart:namespaces> </rampart:optimizeParts>
When working as above in the WSO2 ESB we encounter another problem. Imagine you’ve created a proxy service in the WSO2 ESB for a backend service which accepts an MTOM attachment. Now if the proxy service is not secured with any WS-Encryption then the the WSO2 ESB has no problems. You can try this out with the WSO2 ESB sample 51. The sample only talks about the unsecured proxy case. But you may go ahead and apply a out of the box security policy which involves only signatures and no encryption (Non-repudiation) and find that the sample is still working. But if you turn on a security policy which has encryption (e.g. Sign and encrypt – X509 Authentication) then the sample no longer works. The error at the backend service would look something like follows:
ContentID is null
This can be because of the reason explained earlier in the post, which is the client might be encoding it into the SOAP body payload and encrypting it. If you have followed the work around I have mentioned for that problem, then this is coming because of another problem. The way synapse handles MTOM is, when the SOAP message is received at the proxy service it transforms the SOAP message by adding back the binary attachment into the payload in the relevant part and saves some pointers as XPath expressins as to which were the attachment parts. What happens when leaving Synapse to the backend service is, the pointers are read back and the binary payload is again optimized as MTOM attachments. In our case the MTOM optimization is not handled by Synapse but instead by Rampart. This does not make sure that the message leaving Synapse is optimized. Actually Synapse does not even know that this message consisted an attachment because the Rampart module in the proxy service of the WSO2 ESB has taken care of the security processing and returned the SOAP body to a state where it does not contain any security related tags. That is the part denoted by the XPath
is no more there in the SOAP body. Therefore unless we use another WS-SecurityPolicy for the endpoint of the WSO2 ESB and explicitly do the optimization the message leaving Synapse is not going to be optimized. However there seems to be an issue in that approach as well. It seems to be impossible with Rampart to have a WS-SecurityPolicy with only OptimizedParts configuration specified and no real security applied. Rampart ignores processing the complete policy if it does not find some minimum required configurations in the policy. Therefore this approach is also not going to work.
So the only workaround I was able to do was to write a class mediator for WSO2 ESB and explicitly MTOM optimize the binary payload.
How to try this
1. Setup sample 51 of WSO2 ESB.
2. The source code of the class mediator which does the explicit MTOM optimization can be found here. Add this to
3. The synapse configuration for the proxy service can be found here.
4. The custom security policy to be applied to the proxy service can be found here. Upload this security policy to the registry and apply it to the proxy service by selecting the “Policy From Registry” option.
5. The source code of the client program can be found here. Make sure the lib folder inside the project is added to the Java class path. Also you need to configure the client.properties file according to your environment.
This was tested with WSO2 ESB 4.5.1.