httpClient.GetAsync 抛出异常;怀疑是证书配置 [英] httpClient.GetAsync throws exception; certificate configuration suspected
问题描述
添加一些堆栈跟踪信息
在添加我的虚拟处理程序之前,这是抛出异常的堆栈跟踪:
System.Net.Http.HttpRequestException:发送请求时出错.--->System.Net.WebException:基础连接已关闭:发送时发生意外错误.--->System.IO.IOException:无法从传输连接读取数据:远程主机强行关闭了现有连接.--->System.Net.Sockets.SocketException: 一个现有的连接被远程主机强行关闭在 System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)--- 内部异常堆栈跟踪结束 ---在 System.Net.TlsStream.EndWrite(IAsyncResult asyncResult)在 System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)--- 内部异常堆栈跟踪结束 ---在 System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)在 System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)--- 内部异常堆栈跟踪结束 ---在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)在 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()在 XXXXXXXX.Authentication.Extensions.XXXXXXOpenIDConnectAuthentication.d__8.MoveNext()--- 从上一个抛出异常的位置开始的堆栈跟踪结束 ---在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)在 XXXXXXX.Authentication.Extensions.XXXXXXOpenIDConnectAuthentication.d__6.MoveNext()--- 从上一个抛出异常的位置开始的堆栈跟踪结束 ---在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)在 Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationHandler.d__1a.MoveNext()
添加虚拟处理程序后,异常完全为空 <-- 见注释.异常完全相同,但是当我调试进程时,我的虚拟处理程序中的 return 语句永远不会被命中,所以我的问题的关键变成了还有什么要检查的?">
一个应该添加
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
(来自 System.Net
命名空间)之前调用
await httpClient.GetAsync(address, cancel);
强制使用正确的协议.请参阅博客,其中包含 HttpClient 的详细实验code> 和
ServicePointManager.SecurityProtocol
.
I've got two servers (X and Y) that are trying to communicate, but failing to do so over TLS1.2 (TLS1.1, and TLS1.0 both behave correctly).
I've got a server X that is failing to get a response from localhost
.
The call that is throwing an exception is this line of code
HttpResponseMessage response = await httpClient.GetAsync(address, cancel);
where address is https://localhost/XXXXX/Identity/.well-known/jwks
and cancel is IsCancellationRequested = false
I noticed that the server certificate being presented for https://localhost/XXXXX/Identity/.well-known/jwks
is one that is valid, signed with RSA256, not on a revocation list, etc etc, everything looks good, but the subject is *.testing.corp, which doesn't match the URL I am trying to navigate to. This causes a certificate warning when navigating to https://localhost/XXXXX/Identity/.well-known/jwks
from Chrome on server X, but after manually clicking through it I get the results I expect.
So my thought is that if I can override the cert validation of HttpClient.GetAsync, I should be able to make this work, so I add the following code around my client:
var handler = new WebRequestHandler();
httpClient = new HttpClient(handler);
handler.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(dumbvalidationdeletemeishouldnotbeversioned);
public static bool dumbvalidationdeletemeishouldnotbeversioned(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors err)
{
return true;
}
The interesting bit is that this never hits, when I step to the GetAsync
line of code, a step throws the exception without ever hitting the dummy validation.
What is going on? Why else could this method fail?
Even more context:
EDIT: Related, X is utilizing Identity Server to attempt to authenticate. The failure is occuring when trying to access https://localhost/XXXXX/Identity/.well-known/jwks
I am using IISCrypto to configure the protocols on these machines. (Taking @Oleg's advice in the comments did not change this behavior). I have configured them by clicking the "Best Practices" button and then un-checking TLS1.0 and TLS1.1, so that both servers look like this:
EDIT: Adding some stack trace information
Before I added my dummy handler, this is the thrown exception's stack trace:
System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.TlsStream.EndWrite(IAsyncResult asyncResult)
at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at XXXXXXXX.Authentication.Extensions.XXXXXXOpenIDConnectAuthentication.<ReadJWTKeys>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at XXXXXXX.Authentication.Extensions.XXXXXXOpenIDConnectAuthentication.<MessageRecieved>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationHandler.<AuthenticateCoreAsync>d__1a.MoveNext()
After adding the dummy handler, the exception is completely null <-- see the comments. The exception is exactly the same, but the return statement in my dummy handler is never hit when I debug the process, so the crux of my question changes to "What else is there to check?"
One should add
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
(from System.Net
namespace) before call of
await httpClient.GetAsync(address, cancel);
to force the usage of correct protocol. See the blog with detailed experiments with HttpClient
and ServicePointManager.SecurityProtocol
.
这篇关于httpClient.GetAsync 抛出异常;怀疑是证书配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!