[英].NET Core 3.1: Ignore expired SSL certficate
我正在使用 HttpClient (.NET Core3.1) 從多個來源獲取請求。 我在構造函數中只使用了一個實例,如下所示:
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
_httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("covid19App", "2.0"));
get調用方法如下:
private HttpResponseMessage Get(string url)
{
var response = _httpClient.GetAsync(url).Result;
int count = 0;
while (count < 3 && response.IsSuccessStatusCode)
{
response = _httpClient.GetAsync(url).Result;
count++;
}
return response;
}
在我的 SSL 證書過期之前,我對上述邏輯沒有任何問題。 現在對其中一個源的調用返回異常The SSL connection could not be established, see inner exception
(有關內部異常詳細信息,請參見下文)
經過一番研究,我使用了兩種方法來解決問題,但問題仍然存在。
方法一
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, errors) => true;
_httpClient = new HttpClient(handler);
方法二:
ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
_httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("covid19App", "2.0"));
那么有沒有其他方法可以解決這個問題?
內部異常: The SSL connection could not be established, see inner exception.
=> Authentication failed, see inner exception
=> The message received was unexpected or badly formatted.
編輯:添加了整個異常主體
{
"ClassName":"System.AggregateException",
"Message":"One or more errors occurred.",
"Data":null,
"InnerException":{
"StackTrace":" at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)\r\n at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)",
"Message":"The SSL connection could not be established, see inner exception.",
"Data":{
},
"InnerException":{
"ClassName":"System.Security.Authentication.AuthenticationException",
"Message":"Authentication failed, see inner exception.",
"Data":null,
"InnerException":{
"ClassName":"System.ComponentModel.Win32Exception",
"Message":"The message received was unexpected or badly formatted.",
"Data":null,
"InnerException":null,
"HelpURL":null,
"StackTraceString":null,
"RemoteStackTraceString":null,
"RemoteStackIndex":0,
"ExceptionMethod":null,
"HResult":-2147467259,
"Source":null,
"WatsonBuckets":null,
"NativeErrorCode":-2146893018
},
"HelpURL":null,
"StackTraceString":" at System.Net.Security.SslStream.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)\r\n at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslStream.PartialFrameCallback(AsyncProtocolRequest asyncRequest)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Net.Security.SslStream.ThrowIfExceptional()\r\n at System.Net.Security.SslStream.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)\r\n at System.Net.Security.SslStream.EndProcessAuthentication(IAsyncResult result)\r\n at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)\r\n at System.Net.Security.SslStream.<>c.<AuthenticateAsClientAsync>b__65_1(IAsyncResult iar)\r\n at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)",
"RemoteStackTraceString":null,
"RemoteStackIndex":0,
"ExceptionMethod":null,
"HResult":-2146233087,
"Source":"System.Private.CoreLib",
"WatsonBuckets":null
},
"HelpLink":null,
"Source":"System.Net.Http",
"HResult":-2146233087
},
"HelpURL":null,
"StackTraceString":" at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)\r\n at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)\r\n at System.Threading.Tasks.Task`1.get_Result()\r\n at Covid19.DataService.RawData.RawDataImportService.Get(String url) in E:\\Covid19\\Backend\\Covid19\\Covid19.DataService\\RawData\\RawDataImportService.cs:line 346\r\n at Covid19.DataService.RawData.RawDataImportService.ImportECDPCData(DataSource source, IDictionary`2 populations, IEnumerable`1& locations, List`1& log) in E:\\Covid19\\Backend\\Covid19\\Covid19.DataService\\RawData\\RawDataImportService.cs:line 60\r\n at Covid19.DataService.RawData.RawDataImportService.ImportData(DataSource source, IDictionary`2 populations, IEnumerable`1& locations, List`1& log) in E:\\Covid19\\Backend\\Covid19\\Covid19.DataService\\RawData\\RawDataImportService.cs:line 40",
"RemoteStackTraceString":null,
"RemoteStackIndex":0,
"ExceptionMethod":null,
"HResult":-2146233088,
"Source":"System.Private.CoreLib",
"WatsonBuckets":null,
"InnerExceptions":[
{
"StackTrace":" at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)\r\n at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)",
"Message":"The SSL connection could not be established, see inner exception.",
"Data":{
},
"InnerException":{
"ClassName":"System.Security.Authentication.AuthenticationException",
"Message":"Authentication failed, see inner exception.",
"Data":null,
"InnerException":{
"ClassName":"System.ComponentModel.Win32Exception",
"Message":"The message received was unexpected or badly formatted.",
"Data":null,
"InnerException":null,
"HelpURL":null,
"StackTraceString":null,
"RemoteStackTraceString":null,
"RemoteStackIndex":0,
"ExceptionMethod":null,
"HResult":-2147467259,
"Source":null,
"WatsonBuckets":null,
"NativeErrorCode":-2146893018
},
"HelpURL":null,
"StackTraceString":" at System.Net.Security.SslStream.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)\r\n at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)\r\n at System.Net.Security.SslStream.PartialFrameCallback(AsyncProtocolRequest asyncRequest)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Net.Security.SslStream.ThrowIfExceptional()\r\n at System.Net.Security.SslStream.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)\r\n at System.Net.Security.SslStream.EndProcessAuthentication(IAsyncResult result)\r\n at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)\r\n at System.Net.Security.SslStream.<>c.<AuthenticateAsClientAsync>b__65_1(IAsyncResult iar)\r\n at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)",
"RemoteStackTraceString":null,
"RemoteStackIndex":0,
"ExceptionMethod":null,
"HResult":-2146233087,
"Source":"System.Private.CoreLib",
"WatsonBuckets":null
},
"HelpLink":null,
"Source":"System.Net.Http",
"HResult":-2146233087
}
]
}
雖然這不是最優雅的解決方案,但一種快速而骯臟的方法是調用..
這是您將修復您的方法的地方
private HttpResponseMessage Get(string url)
{
// HACK: set the policy here
ServicePointManager.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) => true;
// note:
// also might be worth taking a look at DangerousAcceptAnyServerCertificateValidator
var response = _httpClient.GetAsync(url).Result;
int count = 0;
while (count < 3 && response.IsSuccessStatusCode)
{
response = _httpClient.GetAsync(url).Result;
count++;
}
return response;
}
更好的方法可能是使用自定義傳出處理程序創建命名或類型化的HttpClient
,該處理程序是從DelegatingHandler繼承的類。
例如
public class IgnoreSSLValidateDelegatingHandler : DelegatingHandler
{
// this commented block could be useful if you want to allow a defined
// group of certicates, rather than just anything out in the wild.
// -------------------------------------------------------------------
//private readonly X509CertificateCollection _certificates;
//public IgnoreSSLValidateDelegatingHandler()
//{
// _certificates = new X509CertificateCollection();
//}
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
System.Threading.CancellationToken cancellationToken)
{
HttpMessageHandler handler = this.InnerHandler;
while (handler is DelegatingHandler)
{
handler = ((DelegatingHandler)handler).InnerHandler;
}
if (handler is HttpClientHandler httpClientHandler
&& httpClientHandler.ServerCertificateCustomValidationCallback == null)
{
httpClientHandler
.ServerCertificateCustomValidationCallback =
(message, cert, chain, errors) => true;
}
return base.SendAsync(request, cancellationToken);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.