views:

389

answers:

1

I have a flex client connecting to a web service that needs an authentication token added as a header, named "Identity". An example of the expected message is:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"&gt;
  <s:Header>
    <Identity xmlns="ns">2188dcbe-0325-4c1e-9a77-19110e0ea99f</Identity>
    <To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none"&gt;https://localhost:8001/MyService&lt;/To&gt;
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none"&gt;ns/MyService/MyOperation&lt;/Action&gt;
  </s:Header>
  <s:Body>
    ...
  </s:Body>
</s:Envelope>

How do I add this kind of header in flex? I've tried using both .addHeader() and .addSimpleHeader, but both of these seem to add sub-elements to the header element like:

<Identity xmlns="ns">
  <Value>34234234-234-234-23-234324</Value>
</Identity>

I know this should be possible, since flex is doing this for the "To" and "Action" headers. The documentation for addHeader seems to suggest you can give it raw XML but I haven't been able to make it work.

Thanks in advance for any pointers!

+1  A: 

There's a couple of ways of doing it. I personally prefer overriding the native SOAPEncoder class which given you access to the actual soap envelope before it is sent. This enables you to have more control and add things like ws-addressing and custom authenication headers.

public class myEncoder 
extends SOAPEncoder
{

private const WSSE_NS:Namespace = new Namespace("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wsswssecurity-secext-1.0.xsd");

    //--------------------------------------------------------------------------
    //
    // Constructor
    // 
    //--------------------------------------------------------------------------
    public function wsseEncoder()
    {
     super();
    }

    //--------------------------------------------------------------------------
    //
    // Methods
    // 
    //--------------------------------------------------------------------------

    /**
     * <p>  override super classes method and recieve raw soap message to manpulate soap envelope
     * </p>
     */
    public override function encodeRequest(args:* = null, headers:Array = null):XML
    {
     //get soap envelope from super class
     var SOAPEnvelope:XML = super.encodeRequest(args, headers);

               //create a header in xml and append it at as a child
     securityHeaderXml = <Security/>;
     securityHeaderXml.setNamespace(WSSE_NS);
     securityHeaderXml.@[mustUnderstand] = 1;

     //set deafult ws-security namespace - filters to all child nodes
     securityHeaderXml.setNamespace(WSSE_NS);

            var id:XML = <Identity/>;
            id.appendChild('value here');
            SOAPEnvelope.prependChild(id);

            SOAPEnvelope.prependChild(headerXml);

     return SOAPEnvelope;
    }


    }
}

Then all you need to do is change the default encoder to this one, if your using generate web service classes go to the serviceBase and look for the method 'Call' and change this line to this

var enc:SOAPEncoder = new myEncoder(); //instead of this -> new SOAPEncoder();

if not iots something like myService.encoder = new myEncoder();

As simple as that.

Obviously override the encoder class gives you alot more control. You can also do the same with the SOAPDecoder class to catch the soap envelope before it get de-serialised.

Hope this helps

Jon

Jon