HttpClient https 请求使用主机名失败,但使用 IP 地址有效
HttpClient https request fails using hostname, but works using IP address
总的来说,我对网络内容不熟悉。不确定这里的问题是什么。
我有一台带 IIS 运行 的机器 ASP NET Core REST API 在 https 上。
我可以通过 Google Chrome 在我的机器上通过
来确认 GET 正在工作
- https://test-machine/api/Example(有效)
- https://10.0.0.21/api/Example(证书无效,N.B。这是预期的,因为证书是针对 "test-machine")
我确认 POST 操作正在使用 Postman(再次忽略无效证书)。
一切都很好,直到我尝试编写客户端应用程序。
我有以下代码。
var ip = Dns.GetHostAddresses("test-machine");
// ip contains the correct IP
using (var hc = new HttpClient())
{
hc.GetAsync(@"https://test-machine/api/Example").Wait();
}
此代码失败。我得到一个 System.AggregateException: 'One or more errors occurred.' 有 4 个异常叠加在一起。
- HttpRequestException: 发送请求时出错。
- WebException:基础连接已关闭:发送时发生意外错误。
- IOException: 无法从传输连接读取数据: 现有连接被远程主机强行关闭。
- SocketException: 现有连接被远程主机强行关闭
如果我更改代码以改用 IP:
using (var hc = new HttpClient())
{
hc.GetAsync(@"https://10.0.0.21/api/Example").Wait();
}
然后请求会按预期工作 即与 Chrome 一样,我遇到证书问题:
AuthenticationException: The remote certificate is invalid according to the validation procedure.
我做错了什么? Dns 显然能够获取到正确的 IP,我在 GetHostAddresses
返回的 IPAddress[]
中看到了它。为什么 HttpClient 没有解析 IP - 或者它解析 IP 有另一个问题?
我试过了
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
和
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
但这没有区别。使用
ServicePointManager.ServerCertificateValidationCallback
也不起作用,因为它从未达到调用回调的程度。在那之前它失败了。
我怀疑问题是因为我不熟悉这些东西,所以我错过了一些重要的东西。
我还应该注意 - 这是一个 .net 4.5.2 控制台应用程序。我尝试移动到 4.6.1,但仍然失败。
我完全看错地方了。问题在于 IIS 设置。
站点绑定出于某种原因明确设置为 10.0.0.21:433。将其切换为 "All Unassigned" - 似乎已经完成了这项工作。
我可能超出了我的理解范围,并且可能是错误的,但我怀疑原因是根据 Wireshark,对查找主机名 IP 的 MDNS 请求的响应返回 ipv6 服务器机器的地址,当然不是 10.0.0.21。再一次,我可能是错的。
我如此不确定的原因是 chrome 似乎在我输入 https://test-machine/api/Example 时一直努力并找到了正确的东西,我无法解释为什么。
总的来说,我对网络内容不熟悉。不确定这里的问题是什么。
我有一台带 IIS 运行 的机器 ASP NET Core REST API 在 https 上。 我可以通过 Google Chrome 在我的机器上通过
来确认 GET 正在工作- https://test-machine/api/Example(有效)
- https://10.0.0.21/api/Example(证书无效,N.B。这是预期的,因为证书是针对 "test-machine")
我确认 POST 操作正在使用 Postman(再次忽略无效证书)。 一切都很好,直到我尝试编写客户端应用程序。
我有以下代码。
var ip = Dns.GetHostAddresses("test-machine");
// ip contains the correct IP
using (var hc = new HttpClient())
{
hc.GetAsync(@"https://test-machine/api/Example").Wait();
}
此代码失败。我得到一个 System.AggregateException: 'One or more errors occurred.' 有 4 个异常叠加在一起。
- HttpRequestException: 发送请求时出错。
- WebException:基础连接已关闭:发送时发生意外错误。
- IOException: 无法从传输连接读取数据: 现有连接被远程主机强行关闭。
- SocketException: 现有连接被远程主机强行关闭
如果我更改代码以改用 IP:
using (var hc = new HttpClient())
{
hc.GetAsync(@"https://10.0.0.21/api/Example").Wait();
}
然后请求会按预期工作 即与 Chrome 一样,我遇到证书问题:
AuthenticationException: The remote certificate is invalid according to the validation procedure.
我做错了什么? Dns 显然能够获取到正确的 IP,我在 GetHostAddresses
返回的 IPAddress[]
中看到了它。为什么 HttpClient 没有解析 IP - 或者它解析 IP 有另一个问题?
我试过了
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
和
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
但这没有区别。使用
ServicePointManager.ServerCertificateValidationCallback
也不起作用,因为它从未达到调用回调的程度。在那之前它失败了。
我怀疑问题是因为我不熟悉这些东西,所以我错过了一些重要的东西。
我还应该注意 - 这是一个 .net 4.5.2 控制台应用程序。我尝试移动到 4.6.1,但仍然失败。
我完全看错地方了。问题在于 IIS 设置。
站点绑定出于某种原因明确设置为 10.0.0.21:433。将其切换为 "All Unassigned" - 似乎已经完成了这项工作。
我可能超出了我的理解范围,并且可能是错误的,但我怀疑原因是根据 Wireshark,对查找主机名 IP 的 MDNS 请求的响应返回 ipv6 服务器机器的地址,当然不是 10.0.0.21。再一次,我可能是错的。
我如此不确定的原因是 chrome 似乎在我输入 https://test-machine/api/Example 时一直努力并找到了正确的东西,我无法解释为什么。