C# HttpClient 和 Windows 身份验证:无法访问已关闭的流
C# HttpClient and Windows Authentication: Cannot access a closed Stream
我正在使用带有处理程序的本机 C# HTTP 客户端来处理 Windows 身份验证,并且我有 ObjectDisposedException
。
using (var httpClientHandler = new HttpClientHandler { Credentials = CredentialCache.DefaultNetworkCredentials })
{
bool disposeHandler = true; //Setting true or false does not fix the problem
using (var httpClient = new HttpClient(httpClientHandler, disposeHandler))
{
using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes("Hello")))
{
// Commenting/uncommenting the line below does not fix the problem
// httpRequestMessage.Headers.Connection.Add("Keep-Alive");
using (var httpResponseMessage = await httpClient.PostAsync("http://SomeUrl", content)) // This line throws an ObjectDisposedException
{
}
}
}
}
有什么想法吗?
您是否尝试过设置 PreAuthenticate = true,它将使用 AD/User 令牌添加授权 header,您应该得到一个 401,然后是第二个请求,带有 header ,建议在fiddler中查看。
httpClientHandler.PreAuthenticate = true;
经过一些新的调查,我 think/fear 在 HttpClientHandler(或 HttpClient):
中有一个 Microsoft 错误
如果我不使用 PostAsync 方法而是使用 SendAsync 方法,我可以用更多选项编写我的请求,尤其是将 HTTP 版本 从 1.1(默认情况下)到 1.0。然后在这种情况下,真正的异常被揭示了(并且它不再是 hidden/overridden 由 ObjectDisposedException 异常)。供您参考,我真正的例外情况如下:
--> System.Net.WebException: 远程服务器返回错误: (401) Unauthorized.
--> System.ComponentModel.Win32Exception: 目标主体名称不正确
(仅供参考,此异常是由于 Active Directory 中用户的 SPN 配置错误所致)
using (var httpClientHandler = new HttpClientHandler { Credentials = CredentialCache.DefaultNetworkCredentials })
{
bool disposeHandler = true; //Setting true or false does not fix the problem
using (var httpClient = new HttpClient(httpClientHandler, disposeHandler))
{
using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes("Hello")))
{
// Commenting/uncommenting the line below does not fix the problem
// httpRequestMessage.Headers.Connection.Add("Keep-Alive");
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://SomeUrl")
{
Content = content,
Version = HttpVersion.Version10
};
using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage)) // This line still throws but with the real exception (and not the ObjectDisposedException)
{
}
}
}
}
注意:降级 HTTP 版本只是为了获取真正的异常消息而进行的黑客攻击,HTTP 1.0 已经很老了。
如有专家分析,将不胜感激。希望这会对其他人有所帮助。
您在 HttpResponseMessage
有机会进行评估之前就将其处理掉了。试试这个。
HttpResponseMessage httpResponseMessage = null;
using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes("Hello")))
{
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://SomeUrl")
{
Content = content,
Version = HttpVersion.Version10
};
using (var httpClient = new HttpClient(httpClientHandler, disposeHandler))
{
httpResponseMessage = await httpClient.SendAsync(httpRequestMessage);
}
}
我正在使用带有处理程序的本机 C# HTTP 客户端来处理 Windows 身份验证,并且我有 ObjectDisposedException
。
using (var httpClientHandler = new HttpClientHandler { Credentials = CredentialCache.DefaultNetworkCredentials })
{
bool disposeHandler = true; //Setting true or false does not fix the problem
using (var httpClient = new HttpClient(httpClientHandler, disposeHandler))
{
using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes("Hello")))
{
// Commenting/uncommenting the line below does not fix the problem
// httpRequestMessage.Headers.Connection.Add("Keep-Alive");
using (var httpResponseMessage = await httpClient.PostAsync("http://SomeUrl", content)) // This line throws an ObjectDisposedException
{
}
}
}
}
有什么想法吗?
您是否尝试过设置 PreAuthenticate = true,它将使用 AD/User 令牌添加授权 header,您应该得到一个 401,然后是第二个请求,带有 header ,建议在fiddler中查看。
httpClientHandler.PreAuthenticate = true;
经过一些新的调查,我 think/fear 在 HttpClientHandler(或 HttpClient):
中有一个 Microsoft 错误如果我不使用 PostAsync 方法而是使用 SendAsync 方法,我可以用更多选项编写我的请求,尤其是将 HTTP 版本 从 1.1(默认情况下)到 1.0。然后在这种情况下,真正的异常被揭示了(并且它不再是 hidden/overridden 由 ObjectDisposedException 异常)。供您参考,我真正的例外情况如下:
--> System.Net.WebException: 远程服务器返回错误: (401) Unauthorized.
--> System.ComponentModel.Win32Exception: 目标主体名称不正确
(仅供参考,此异常是由于 Active Directory 中用户的 SPN 配置错误所致)
using (var httpClientHandler = new HttpClientHandler { Credentials = CredentialCache.DefaultNetworkCredentials })
{
bool disposeHandler = true; //Setting true or false does not fix the problem
using (var httpClient = new HttpClient(httpClientHandler, disposeHandler))
{
using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes("Hello")))
{
// Commenting/uncommenting the line below does not fix the problem
// httpRequestMessage.Headers.Connection.Add("Keep-Alive");
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://SomeUrl")
{
Content = content,
Version = HttpVersion.Version10
};
using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage)) // This line still throws but with the real exception (and not the ObjectDisposedException)
{
}
}
}
}
注意:降级 HTTP 版本只是为了获取真正的异常消息而进行的黑客攻击,HTTP 1.0 已经很老了。
如有专家分析,将不胜感激。希望这会对其他人有所帮助。
您在 HttpResponseMessage
有机会进行评估之前就将其处理掉了。试试这个。
HttpResponseMessage httpResponseMessage = null;
using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes("Hello")))
{
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://SomeUrl")
{
Content = content,
Version = HttpVersion.Version10
};
using (var httpClient = new HttpClient(httpClientHandler, disposeHandler))
{
httpResponseMessage = await httpClient.SendAsync(httpRequestMessage);
}
}