tags:

views:

518

answers:

1

Hi all,

I have a web application that communicates to a WCF service through a WCF client. At the point my code is invoked, authentication cookies have been issued and I have a dependency on an ASMX service that expects those authentication cookies.

I need to pass the cookies from the web application through the WCF client to the WCF service to the ASMX service.

Any ideas? It looks like my best bet may be setting allowCookies to false, parsing out the cookie headers, attempting to re-create them on the WCF service and then attaching them to the SOAP request.

Note: I looked at this article, which seems close but not quite applicable to this question. In the linked scenario, an ASMX service is creating cookies, which must be persisted to a subsequent ASMX service by the same WCF client.

+4  A: 

Ok, so there's two main things that need to occur:

  1. Get the cookie from the web app context to the WCF service
  2. Get the cookie from the WCF service to the ASMX service

NOTE: Because you didn't specify, I'm going to assume that you're using a WCF client within your WCF service to talk to the ASMX service. If this is not the case please let me know and I will revise this post accordingly.

Step #1:

I would recommend writing an IClientMessageInspector which you bind to your client endpoints using an IEndpointBehavior. In your implementation of IClientMessageInspector::BeforeSendRequest you basically read the cookie out of the current HttpContext::Request::Cookies collection and append the value as a message header. That would look a little something like this:

public void BeforeSendRequest(ref Message request, IClientChannel channel)
{
    // Get the cookie from ASP.NET
    string cookieValue = HttpContext.Current.Request.Cookies["MyCookieName"].Value;   

    // Create a header that represents the cookie
    MessageHeader myCookieNameHeader = MessageHeader.CreateHeader("MyCookieHeaderName", "urn:my-custom-namespace", cookieValue);   

    // Add the header to the message
    request.Headers.Add(myCookieNameHeader);
}

One you configure the endpoint with this message inspector every logical request will automatically flow the cookie value through as a header to your WCF service. Now, since your WCF service doesn't actually care about the header itself, it can basically ignore it. In fact, if you only did this step, you should be able to run all your code right now and not experience any difference.

Step #2:

Now we need the cookie to go from the WCF service to the ASMX service. Once again all you need to do is implement an IClientMessageInspector, except your BeforeSendMessageRequest is going to be a little different:

public void BeforeSendRequest(ref Message request, IClientChannel channel)
{
    // Get the cookie value from the custom header we sent in from step #1
    string cookieValue = OperationContext.Current.IncomingMessageHeaders.GetHeader<string>("MyCookieHeaderName", "urn:my-custom-namespace");

    HttpRequestMessageHeaderProeperty httpRequestMessageHeaderProperty;
    MessageProperties outgoingMessageProperties = OperationContext.Current.OutgoingMessageProperties;

    // Get the HttpRequestMessageHeaderProperty, if it doesn't already exist we create it now
    if(!outgoingMessageProperties.TryGetValue(HttpRequestMessageHeaderProperty.Name, out httpRequestMessageHeaderProperty))
    {
        httpRequestmessageHeaderProperty = new HttpRequestMessageHeaderProperty();

        outgoingMessageProperties.Add(HttpRequestMessageHeaderProperty.Name, httpRequestmessageHeaderProperty);
    }

    // Set the cookie header to our cookie value (note: sample assumes no other cookies set)
    httpRequestmessageHeaderProperty.Headers[HttpRequestHeader.Cookie] = cookieValue;
}

Once again you need to bind this to the endpoint for your ASMX service using an IEndpointBehavior and every logical request you make will automatically pass the cookie through.

Drew Marsh