.net core 2.0 HTTPS request fails using HttpClient 安全错误
最近.net core 项目中遇到一个问题,通过Httpclient 访问https的接口报错,错误如下:
WinHttpException: A security error occurred System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult() System.Net.Http.WinHttpHandler+<StartRequest>d__105.MoveNext() HttpRequestException: An error occurred while sending the request. System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult() System.Net.Http.HttpClient+<FinishSendAsync>d__58.MoveNext() System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) System.Runtime.CompilerServices.TaskAwaiter.GetResult() MyApp.Web.Controllers.HomeController.Test() in HomeController.cs var response = client.GetAsync("https://someurl.com/api.php?arg1=some&arg2=test").GetAwaiter().GetResult(); lambda_method(Closure , object , Object[] ) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeActionMethodAsync>d__27.MoveNext()
通过排查发现是.NETFramework 4.6包括一个新的安全特性,它阻止连接的不安全密码和散列算法。
可以通过下面的解决方案处理:
using (var handler = new HttpClientHandler()) { handler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls; using (HttpClient client = new HttpClient(handler)) { string requestObjJson = requestObj.ToJson(); var address = new Uri($"https://yourcompany.com/"); string token = GetToken(); client.BaseAddress = address; client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); var contentData = new StringContent(requestObjJson, System.Text.Encoding.UTF8, "application/json"); using (var response = await client.PostAsync("yourcompany/api", contentData)) { var content = response.Content.ReadAsStringAsync(); var taskResult = content.Result; JObject resultObj = JObject.Parse(taskResult); return resultObj; } } }
需要注意的是,对于.NET core 2.0,您需要使用HttpClientHandler而不是ServicePointManager.