【发布时间】:2017-08-02 10:32:57
【问题描述】:
我正在使用以下代码并得到HttpRequestException 异常:
using (var handler = new HttpClientHandler())
{
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.SslProtocols = SslProtocols.Tls12;
handler.ClientCertificates.Add(new X509Certificate2(@"C:\certificates\cert.pfx"));
// I also tried to add another certificates that was provided to https access
// by administrators of the site, but it still doesn't work.
//handler.ClientCertificates.Add(new X509Certificate2(@"C:\certificates\cert.crt"));
//handler.ClientCertificates.Add(new X509Certificate2(@"C:\certificates\cert_ca.crt"));
using (var client = new HttpClient(handler))
{
var response = client.GetAsync("https://someurl.com/api.php?arg1=some&arg2=test").GetAwaiter().GetResult();
// ^ HttpRequestException: An error occurred while sending the request.
}
}
例外:
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()
我还尝试将相同的证书导出到 Windows 证书商店并通过 Google Chrome 使用它,它工作正常(浏览器要求我确认已安装的证书,然后加载资源)。
为什么它在我的代码中不起作用?
更新
我还尝试添加回调来验证证书:
handler.ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) =>
{
// I set a breakpoint to this point but it is not catched.
return true;
};
更新2
证书使用 SHA-1。 Neil Moss 在 support for SHA1 certs is being withdrawn 的 cmets 中被提及。 如果这是它无法正常工作的真正原因,是否有解决方法?
解决方案
感谢 Neil Moss 的解决方案。他建议将 Tls 标志用于 SSL 协议。
handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
但它还需要以下内容:
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
在我添加了这个之后,它就可以正常工作了。
【问题讨论】:
-
请提供错误的完整详细信息:类型、消息和堆栈跟踪。如果有内部异常,那是什么?
-
嗨@Richard,我已经用异常消息和堆栈跟踪更新了我的问题。
-
澄清一下,您是尝试通过 客户端证书 通过 HTTPS 连接,还是尝试包含自签名 服务器证书 您希望将其视为有效吗?
-
完全题外话:为什么
client.GetAsync(…).GetAwaiter().GetResult()?为什么不简单地await client.GetAsync(…)? -
您的证书是否使用 SHA1 签名?正在撤销对 SHA1 证书的支持 - 可能相关吗? blogs.windows.com/msedgedev/2016/04/29/sha1-deprecation-roadmap
标签: c# asp.net-core .net-core x509certificate x509certificate2