Question

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.

Était-ce utile?

La 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. For more information, see this page, which I find very useful and clear about NTLM scheme:

http://www.innovation.ch/personal/ronald/ntlm.html

Autres conseils

Maybe it is a bit too late for it, but you have to set the UnsafeAuthenticatedConnectionSharing property to true in the WebRequestHandler (it extends HttpClientHandler).

This way connections are kept alive by allowing the HttpClient to "share" the authentication among other requests, allowing at the same time the connections to be kept alive (you can't do this manually even by setting the header yourself). Bear in mind that you should also have the appropriate persistent authorization in the server, either with authPersistNonNTLM for Kerberos or with authPersistSingleRequest for NTLM.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top