Search code examples
c#.net-4.5wcf-web-apidotnet-httpclient

HttpClient authentication header not getting sent


I'm trying to use an HttpClient for a third-party service that requires basic HTTP authentication. I am using the AuthenticationHeaderValue. Here is what I've come up with so far:

HttpRequestMessage<RequestType> request = 
    new HttpRequestMessage<RequestType>(
        new RequestType("third-party-vendor-action"),
        MediaTypeHeaderValue.Parse("application/xml"));
request.Headers.Authorization = new AuthenticationHeaderValue(
    "Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(
        string.Format("{0}:{1}", "username", "password"))));

var task = client.PostAsync(Uri, request.Content);
ResponseType response = task.ContinueWith(
    t =>
    {
        return t.Result.Content.ReadAsAsync<ResponseType>();
    }).Unwrap().Result;

It looks like the POST action works fine, but I don't get back the data I expect. Through some trial and error, and ultimately using Fiddler to sniff the raw traffic, I discovered the authorization header isn't being sent.

I've seen this, but I think I've got the authentication scheme specified as a part of the AuthenticationHeaderValue constructor.

Is there something I've missed?


Solution

  • Your code looks like it should work - I remember running into a similar problem setting the Authorization headers and solved by doing a Headers.Add() instead of setting it:

    request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "username", "password"))));
    

    UPDATE: It looks like when you do a request.Content, not all headers are being reflected in the content object. You can see this by inspecting request.Headers vs request.Content.Headers. One thing you might want to try is to use SendAsync instead of PostAsync. For example:

    HttpRequestMessage<RequestType> request = 
         new HttpRequestMessage<RequestType>(
             new RequestType("third-party-vendor-action"),
             MediaTypeHeaderValue.Parse("application/xml"));
    
    request.Headers.Authorization = 
        new AuthenticationHeaderValue(
            "Basic", 
            Convert.ToBase64String(
                System.Text.ASCIIEncoding.ASCII.GetBytes(
                    string.Format("{0}:{1}", "username", "password"))));
    
     request.Method = HttpMethod.Post;
     request.RequestUri = Uri;
     var task = client.SendAsync(request);
    
     ResponseType response = task.ContinueWith(
         t => 
             { return t.Result.Content.ReadAsAsync<ResponseType>(); })
             .Unwrap().Result;