Christophe Keller
Christophe Keller

Reputation: 834

How to set http cookies (headers) in HTTP request

I'm trying to set up a WCF service hosted in IIS in ASP.Net compatibility mode that is protected via Forms Authentication and accessed via a .Net User Control in IE. (see Secure IIS hosted WCF service for access via IE hosted user control).

The User Control in IE is needed because it uses a specific third-party control for which there doesn't exist anything comparable in Silverlight or AJAX.

So I need the UserControl to set the authentication and session id cookies in the http request headers before it accesses the WCF service. My approach is to set up a Message inspector that does this.

So I've defined the Message Inspector:

public class CookieInspector : IClientMessageInspector {

    public void AfterReceiveReply(ref Message reply, object correlationState) {
    }

    public object BeforeSendRequest(
            ref Message request, 
            IClientChannel channel) {

        HttpRequestMessageProperty messageProperty;

        if (request.Properties.ContainsKey(HttpRequestMessageProperty.Name)) {
            messageProperty = (HttpRequestMessageProperty) request.Properties[
                HttpRequestMessageProperty.Name
            ];
        }
        else {
            messageProperty = new HttpRequestMessageProperty();
            request.Properties.Add(
                HttpRequestMessageProperty.Name, 
                messageProperty
            );
        }

        // Set test headers for now...
        messageProperty.Headers.Add(HttpRequestHeader.Cookie, "Bob=Great");
        messageProperty.Headers.Add("x-chris", "Beard");

        return null;
    }
}

and an Endpoint behaviour:

public class CookieBehavior : IEndpointBehavior {
    public void AddBindingParameters(
            ServiceEndpoint endpoint, 
            BindingParameterCollection bindingParameters) {
    }

    public void ApplyClientBehavior(
            ServiceEndpoint endpoint, 
            ClientRuntime clientRuntime) {
        clientRuntime.MessageInspectors.Add(new CookieInspector());
    }

    public void ApplyDispatchBehavior(
            ServiceEndpoint endpoint, 
            EndpointDispatcher endpointDispatcher) {
    }

    public void Validate(ServiceEndpoint endpoint) {
    }
}

and I configure and create my channel and WCF client in code:

var ea = new EndpointAddress("http://.../MyService.svc");

// EDIT: Http cookies can't be set with WSHttpBinding :-(
// var binding = WSHttpBinding();
var binding = new BasicHttpBinding();


// Disable automatically managed cookies (which enables user cookies)
binding.AllowCookies = false;


binding.MaxReceivedMessageSize = 5000000;
binding.ReaderQuotas.MaxStringContentLength = 5000000;
var cf = new ChannelFactory<ITranslationServices>(binding, ea);
cf.Endpoint.Behaviors.Add(new CookieBehavior());    

ITranslationServices service = cf.CreateChannel();

However when I look at my request with Fiddler, the http header and cookie aren't set, and I have no clue why. I've read various articles on the Net, Stackoverflow etc that basically say that it should work, but it doesn't. Either I'm missing something obvious, or there's a bug in WCF or something else?

Upvotes: 2

Views: 6619

Answers (2)

WLY
WLY

Reputation: 1

WSHttpBinding may be composed of more than one physical message to one logical message. So when successive physical calls are made, they may not be carrying the cookie appropriately

Upvotes: 0

Christophe Keller
Christophe Keller

Reputation: 834

Well I figured it out, if I use a basicHttpBinding instead of a WSHttpBinding it works. No idea why though...

Upvotes: 3

Related Questions