Having WSO2 ESB 4.8.1 we try to sign the outgoing messages to the backend system. The signing itself works well, except when a custom SOAP header is present on the request (the custom header required by the backend system )
Example:
- The proxy service is very simple, effectively only a simple proxy to the defined endpoint
- Endpoint is defined as an address endpoint with outbound and inbound policy
- policy is defined as an asymmetric signing policy
Example client request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/ >
<soapenv:Header>
<head:myHeader xmlns:head="http://mytest.headers/header">
<head:messageId>594fcbc4-d3d4-11e5-ab30-625662874444</head:messageId>
</head:myHeader>
</soapenv:Header>
<soapenv:Body>
<ser:listTypesRequest>
</ser:listTypesRequest>
</soapenv:Body>
On the backend following message is received, note the head:messageId element in the security header which renders the Security header invalid (at least the backend system claims it cannot handle the head:messageId element from the security token). If I intercept and cut off the head:messageId element from the Security header, the backend considers the message valid.
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:head="http://fsb.belgium.be/header" xmlns:ser="http://cjcs-cg.just.fgov.be/service-v1.0">
<soapenv:Header>
<head:myHeader xmlns:head="http://mytest.headers/header">
<head:messageId>594fcbc4-d3d4-11e5-ab30-625662870762</head:messageId>
</head:myHeader>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-37">
<wsu:Created>2016-05-20T14:30:54.827Z</wsu:Created>
<wsu:Expires>2016-05-20T14:35:54.827Z</wsu:Expires>
</wsu:Timestamp>
<head:messageId xmlns:head="http://mytest.headers/header">594fcbc4-d3d4-11e5-ab30-625662870762</head:messageId>
<wsse:BinarySecurityToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="CertId-2541F55E8971D834D1146375465482873">MIIH..long certificate here... ==</wsse:BinarySecurityToken>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-38">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#Id-1094174436">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>P571zv6yej1+7gAVD6gSum61Vz0=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#Timestamp-37">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>+APmWSyt57oePoeY1KdKjaCNI6E=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
DDZ6PefoInpfaaL7Ge/SCt02KJRP9xGA2Jd8YJXuzfMF+hIQybEm14JcjLB0YsQVbpVbonO8D
DDZ6 deleted =
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-2541F55E8971D834D1146375465482974">
<wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-2541F55E8971D834D1146375465482975">
<wsse:Reference URI="#CertId-2541F55E8971D834D1146375465482873" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soapenv:Header>
<soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-1094174436">
<ser:listTypesRequest>
</ser:listTypesRequest>
</soapenv:Body>
</soapenv:Envelope>
I've tried to clean and define the custom SOAP Header in the proxy flow, but then the Rampart throws an exception that it cannot convert the the OMElement to the SOAP Header:
Caused by: java.lang.ClassCastException: org.apache.axiom.om.impl.llom.OMElementImpl cannot be cast to org.apache.axiom.soap.SOAPHeaderBlock
at org.apache.rampart.util.Axis2Util.getDocumentFromSOAPEnvelope(Axis2Util.java:99)
So - the question:
- is it possible to sign the WS request and not having part of the custom header in the security header? I assume it can be Rampart bug, but - is it possible to overcome it?
- can I insert custom SOAP Headers to the signed message before signing it? (indeed, in theory yes, but how do I keep Rampart happy with it)
Thank you in advance for any help / hint.