Search code examples
c#httpwebrequestntlmnetworkcredentials

How to 'share' NTLM authentication across multiple HttpWebRequests?


My C# app hits a web server that uses NTLM authentication.

I find that each request made to the server (using a new HttpWebRequest) is individually authenticated. In other words, every request results in a 401 response, after which an NTLM handshaking conversation occurs before I then get the actual response.

e.g.:

First GET request:

-> GET xyz 
<- 401 error (WWW-Authenticate:NTLM)

-> GET xyz (Authorization:NTLM base64stuff)
<- 401 error (WWW-Authenticate:NTLM base64stuff)

-> GET xyz (Authorization: base64stuff)
<- 200

Subsequent requests:

-> GET xyz (Authorization:NTLM base64stuff)
<- 401 error (WWW-Authenticate:NTLM) //can this request be avoided?

-> GET xyz (Authorization: base64stuff)
<- 200

(initially, with PreAuthenticate set to false, the subsequent requests looked like the first request - i.e. three underlying requests per 'request')

Is there a way to 'share' the authentication performed on the first request to the server with subsequent HttpWebRequests?

I thought perhaps the UnsafeAuthenticatedConnectionSharing property would allow me to do this, but setting it to true for all HttpWebRequest objects used in the app has no effect.

However if I set PreAuthenticate to true, one less 401 response happens for each request after the first one.


Solution

  • Last request sent after NTLM is performed (the one that results in a 200 response) contains an auth header that tells the server that you have the correct credentials.

    I'm not sure if the client class has the feature to keep this by its own, but if you find some way to retain this header and add it to your subsequent requests it should work fine.


    Update: NTLM authenticates a connection, so you need to keep your connection open using Keep-Alive header. The client class should provide some settings for this.