如何“分享”跨多个 HttpWebRequest 的 NTLM 身份验证?
我的 C# 应用程序访问使用 NTLM 身份验证的 Web 服务器。
我发现向服务器发出的每个请求(使用新的 HttpWebRequest)都是单独进行身份验证的。换句话说,每个请求都会产生 401 响应,之后会发生 NTLM 握手对话,然后我才能获得实际响应。
例如:
第一个 GET 请求:
-> GET xyz
<- 401 error (WWW-Authenticate:NTLM)
-> GET xyz (Authorization:NTLM base64stuff)
<- 401 error (WWW-Authenticate:NTLM base64stuff)
-> GET xyz (Authorization: base64stuff)
<- 200
后续请求:(
-> GET xyz (Authorization:NTLM base64stuff)
<- 401 error (WWW-Authenticate:NTLM) //can this request be avoided?
-> GET xyz (Authorization: base64stuff)
<- 200
最初,将 PreAuthenticate 设置为 false,后续请求看起来像第一个请求 - 即每个“请求”三个底层请求)
有没有办法“共享”对第一个请求执行的身份验证通过后续的 HttpWebRequest 向服务器发出请求?
我想也许 UnsafeAuthenticatedConnectionSharing
< /a> 属性允许我执行此操作,但对于应用程序中使用的所有 HttpWebRequest 对象将其设置为 true 没有效果。
但是,如果我设置 PreAuthenticate
< /a> 设置为 true,第一个请求之后的每个请求都会少发生一次 401 响应。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
执行 NTLM 后发送的最后一个请求(导致 200 响应的请求)包含一个 auth 标头,告诉服务器您拥有正确的凭据。
我不确定客户端类是否具有自行保留此标头的功能,但如果您找到某种方法来保留此标头并将其添加到后续请求中,它应该可以正常工作。
更新:NTLM 对连接进行身份验证,因此您需要使用 Keep-Alive 标头保持连接打开。客户端类应该为此提供一些设置。
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.
也许现在有点晚了,但您必须在 WebRequestHandler(它扩展了 HttpClientHandler)中将 UnsafeAuthenticatedConnectionSharing 属性设置为 true。
通过这种方式,通过允许 HttpClient 在其他请求中“共享”身份验证来保持连接,同时允许连接保持活动状态(即使您自己设置标头,也无法手动执行此操作)。请记住,您还应该在服务器中拥有适当的持久授权,可以使用用于 Kerberos 的
authPersistNonNTLM
或使用用于 NTLM 的authPersistSingleRequest
。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 withauthPersistSingleRequest
for NTLM.