httpClient.GetAsync 抛出异常;怀疑是证书配置 [英] httpClient.GetAsync throws exception; certificate configuration suspected

查看:43
本文介绍了httpClient.GetAsync 抛出异常;怀疑是证书配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

添加一些堆栈跟踪信息

在添加我的虚拟处理程序之前,这是抛出异常的堆栈跟踪:

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.

TL;DR version (somewhat)

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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆