8

When using the HttpClient in .net 4.5 to do basic authentication I'm finding that it's issuing 2 requests.

The first fails with a HTTP/1.1 401 Unauthorized and then it resends the request to which we get a HTTP/1.1 200 OK.

Any ideas on how to stop it from doing this?

var credential = new NetworkCredential 
{ 
    UserName = username, 
    Password = password 
}
var httpClientHandler = new System.Net.Http.HttpClientHandler
{
    Credentials = credential
};
httpClient = new HttpClient(httpClientHandler, true)
{
    BaseAddress = address
};

4 Answers 4

5

Try setting this:

httpClientHandler.PreAuthenticate = true;

I think the very first request will still get the initial 401, but subsequent request to the same URI up to the last forward slash should always send the authentication headers without the 401.

Sign up to request clarification or add additional context in comments.

7 Comments

I thought that as well, but the documentation suggests that won't work - it will still not send authentication information for the first request.
Yeah, I saw the same thing, which makes me assume that there's no way to make HttpClient do this, unless you manually create the header for the initial request (which is obviously quite easy, but obnoxious to do).
I tried PreAuthenticate = true, but it doesn't seem to change anything, I still get the 401 followed by a 200
I can get it to work if I forgo using the NetworkCredentials class and add the following httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes(username + ":" + password))); but that really sucks :)
Customer is always right, so I assume you can't just tell them to stop being idiots who log WWW-Authenticate calls ;). How about writing an extension method to HttpClient where you implement the code you posted above? That will work like you tested, while also looking clean in the code.
|
1

You could try setting HttpClientHandler.PreAuthenticate as per Tobberoth's answer, although the documentation for that suggests it will only help after the very first request:

With the exception of the first request, the PreAuthenticate property indicates whether to send authentication information with subsequent requests to a Uri that matches the specific Uri up to the last forward slash without waiting to be challenged by the server.

It won't help for the very first request, but it may help to reduce the number of round trips after that.

Another thing to try is including "Authorization" in HttpClient.DefaultRequestHeaders. I'd be slightly surprised if that worked, but it's worth trying, at least.

2 Comments

We still get 401's with PreAuthenitcate = true, but just not as many, running an integratation test shows that for 9 requests we still get 3 401 responses, whereas without this setting we would get 9.
@IanOakes Any chance the HttpClient was being disposed and therefore closing the connection. That would probably cause the the 401 dance again.
0

While looking for an answer to another problem I have with the NetworkCredentials I stumbled across two questions with answers that might be the ones you're looking for:

Here the answer says that at least WebRequest has the default behaviour of only sending the credentials after getting a 401. And here it seems that the solution might be using a CredentialCache.

I'm not sure if the CredentialCache works with the HttpClient, but if it doesn't you could switch to WebRequest or also WebClient, or maybe this information just brought you on the path to another solution.

Comments

0

The best to avoid the second call is to create and set Authorization header manually: https://stackoverflow.com/a/4346843/1143824

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.