Namespaces-prefixes in SOAP-headers

Posted by Jens Dahlin on 03-Oct-2014 08:43

Still struggling (in vain so far) with WS-Security - haven't given up just yet. 

There seems to be some inconsistencies in how the namespace prefixes works in SOAP-headers.

I need to create a header like this:

<MessageID xmlns="http://www.w3.org/2005/08/addressing">0c8791a0-36d8-f0eb-4024-3dc5be30ab88</MessageID>
    <Action xmlns="http://www.w3.org/2005/08/addressing">http://webservices.amadeus.com/FMPTBQ_14_1_1A</Action>
    <To xmlns="http://www.w3.org/2005/08/addressing">https://nodeD1.test.webservices.amadeus.com/1ASIWIBNAIT</To>
    <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <UsernameToken Id="UsernameToken-1">
        <Username>XXXXXX</Username>
        <Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">bktxTTlDMU0=</Nonce>
        <Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">feoLkQ2jFf9C5YAbt8p5znJ8lnk=</Password>
        <Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2014-10-03T11:42:47:506Z</Created>
      </UsernameToken>
    </Security>
    <AMA_SecurityHostedUser xmlns="http://xml.amadeus.com/2010/06/Security_v1">
      <UserID AgentDutyCode="SU" POS_Type="1" PseudoCityCode="YYYYY" RequestorType="U"/>
    </AMA_SecurityHostedUser>

So there are five different header entries (MessageId, Action, To, Security and AMA_SecurityHostedUser) and three different namespaces (MessageId, Acrtion and To share the same).

I try to create this header using one X-DOCUMENT with five children and then add those children to the soap-header. Saving the entire X-DOCUMENT gives me a correct XML-document without any namespace prefixes. This way I can also insert the "recommended but not mandatory" prefixes that exists for WS-Security (wsse for security, wsa for addressing etc).

However: hijacking the actual call to the Webservice via Fiddler shows me what seems to be an erroneous XML-structure. All five header-tags have the same namespace-prefix (ns0) but different namespaces. Regardless if I create the headers like "prefix:name", "name" use NAMESPACE-PREFIX or not. 

I've played around with

hNode:NAMESPACE-PREFIX = "prefix1".

CREATE-NODE-NAMESPACE(hNode, cNS, "prefix1:node", "ELEMENT"). And so on but I get no real change. 

The only thing I can see is that CREATE-NODE (hNode, "node", "ELEMENT") gives me nodes without prefix and I can use those for child nodes to one of the five different header entries. Defining a header entry itself requires a namespace (otherwise error 11767 is thrown).

This is what I end up with:

<SOAP-ENV:Header>
<ns0:MessageID xmlns:ns0="http://www.w3.org/2005/08/addressing">7ec5b5d8-4e9e-e550-19ac-50487bd89dba</ns0:MessageID>
<ns0:Action xmlns:ns0="http://www.w3.org/2005/08/addressing">http://webservices.amadeus.com/FMPTBQ_14_1_1A</ns0:Action>
<ns0:To xmlns:ns0="http://www.w3.org/2005/08/addressing">https://noded1.test.webservices.amadeus.com/1ASIWIBNAIT</ns0:To>
<ns0:Security xmlns:ns0="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
  <UsernameToken Id="UsernameToken-1">
    <Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">eXRpem85aUg=</Nonce>
    <Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">OEgv1O9GGoVWQoQ/7fUZvfn5Nqw=</Password>
    <Created>2014-10-01T08:52:54:291Z</Created>
  </UsernameToken>
</ns0:Security>
etc

Could this perhaps be this bug: http://knowledgebase.progress.com/articles/Article/000040661

A shortened example of how I create xml and the headers:

DEFINE VARIABLE hAMA_SecurityHostedUser AS HANDLE      NO-UNDO.
DEFINE VARIABLE hTXT                    AS HANDLE      NO-UNDO.
DEFINE VARIABLE ghSoapHeader            AS HANDLE      NO-UNDO.
DEFINE VARIABLE hXDocument              AS HANDLE      NO-UNDO.
DEFINE VARIABLE hRootNode               AS HANDLE      NO-UNDO.
DEFINE VARIABLE hADDMessageID           AS HANDLE      NO-UNDO.
DEFINE VARIABLE hSoapHeaderEntryRef1    AS HANDLE      NO-UNDO.
DEFINE VARIABLE hSoapHeaderEntryRef5    AS HANDLE      NO-UNDO.
DEFINE VARIABLE hUSerId                 AS HANDLE      NO-UNDO.
DEFINE VARIABLE cNSAmaSec               AS CHARACTER   NO-UNDO.
DEFINE VARIABLE cNSAddressing           AS CHARACTER   NO-UNDO.
DEFINE VARIABLE cMessageID              AS CHARACTER   NO-UNDO.
DEFINE VARIABLE cOfficeId               AS CHARACTER   NO-UNDO.

/* Create xml-document and nodes as well as soap-headers */
CREATE X-DOCUMENT hXDocument.
CREATE X-NODEREF hRootNode.
CREATE X-NODEREF hADDMessageID.
CREATE X-NODEREF hTxt.
CREATE X-NODEREF hUSerId.
CREATE X-NODEREF hAMA_SecurityHostedUser.
CREATE SOAP-HEADER ghSoapHeader.
CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryRef1.
CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryRef5.

/* Namespaces */
ASSIGN 
    cNSAddressing     = "http://www.w3.org/2005/08/addressing"
    cNSAmaSec         = "http://xml.amadeus.com/2010/06/Security_v1".

/* Bogus data */
ASSIGN 
    cMessageId = "ABC123"
    cOfficeID  = "EFG456".


hXDocument:CREATE-NODE(hRootNode, "root", "element").
hXDocument:INSERT-BEFORE(hRootNode, ?).


/**** First header entry, namespace 1 ****/
ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref1).
hXDocument:CREATE-NODE-NAMESPACE(hADDMessageID, cNSAddressing, "MessageID", "ELEMENT").
hRootNode:APPEND-CHILD(hAddMessageID).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cMessageId.
hADDMessageId:APPEND-CHILD(hTxt).
hSoapHeaderEntryref1:SET-NODE(hADDMessageID).

/**** Second header entry, namespace 2 ****/
ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref5).
hXDocument:CREATE-NODE-NAMESPACE(hAMA_SecurityHostedUser, cNSAMASec, "AMA_SecurityHostedUser", "ELEMENT").
hXDocument:CREATE-NODE(hUserID, "UserID", "ELEMENT").
hUserID:SET-ATTRIBUTE("AgentDutyCode", "SU"). 
hUserID:SET-ATTRIBUTE("RequestorType", "U").
hUserID:SET-ATTRIBUTE("PseudoCityCode", cOfficeId).
hUserID:SET-ATTRIBUTE("POS_Type", "1").
hAMA_SecurityHostedUser:APPEND-CHILD(hUserID).
hSoapHeaderEntryref5:SET-NODE(hAMA_SecurityHostedUser).
hRootNode:APPEND-CHILD(hAMA_SecurityHostedUser).
hXDocument:SAVE("file", "c:\temp\test_3.xml").

/* Delete this with output parameter "lDeleteOnDone" in real environment */
DELETE OBJECT ghSoapHeader.
DELETE OBJECT hSoapHeaderEntryRef1.  
DELETE OBJECT hSoapHeaderEntryRef5.  

/* Clean up */
DELETE OBJECT hADDMessageID.         
DELETE OBJECT hUSerId.               
DELETE OBJECT hAMA_SecurityHostedUser.
DELETE OBJECT hRootNode.             
DELETE OBJECT hXDocument.           
DELETE OBJECT hTxt.

All Replies

This thread is closed