将客户端证书添加到.net核心Httpclient

我正在玩.Net Core并构建一个利用支付API的API。 需要将客户端证书添加到双向SSL身份validation请求中。 如何使用HttpClient在.Net Core中实现这一目标?

我查看了各种文章,发现HttpClientHandler没有提供添加客户端证书的任何选项。

请指教

我有一个类似的项目,我通过服务在服务之间以及移动和桌面之间进行通信。

我们使用EXE中的Authenticode证书来确保它是我们正在执行请求的二进制文件。

在请求方(简化为post)。

Module m = Assembly.GetEntryAssembly().GetModules()[0]; using (var cert = m.GetSignerCertificate()) using (var cert2 = new X509Certificate2(cert)) { var _clientHandler = new HttpClientHandler(); _clientHandler.ClientCertificates.Add(cert2); _clientHandler.ClientCertificateOptions = ClientCertificateOption.Manual; var myModel = new Dictionary { { "property1","value" }, { "property2","value" }, }; using (var content = new FormUrlEncodedContent(myModel)) using (var _client = new HttpClient(_clientHandler)) using (HttpResponseMessage response = _client.PostAsync($"{url}/{controler}/{action}", content).Result) { response.EnsureSuccessStatusCode(); string jsonString = response.Content.ReadAsStringAsync().Result; var json = new Newtonsoft.Json.JsonSerializer(); var myClass = JsonConvert.DeserializeObject(json); } } 

然后,我在获取请求的操作上使用以下代码

 X509Certificate2 clientCertInRequest = Request.HttpContext.Connection.ClientCertificate; if (!clientCertInRequest.Verify() || !AllowedCerialNumbers(clientCertInRequest.SerialNumber)) { Response.StatusCode = 404; return null; } 

我们宁愿提供404而不是500,因为我们喜欢那些试图获取错误请求的人,而不是让他们知道他们“在正确的轨道上”

我按照以下步骤为我的平台(Linux Mint 17.3)运行了全新安装: https : //www.microsoft.com/net/core 。 我创建了一个针对netcoreapp1.0框架的新控制台应用程序,能够提交客户端证书; 但是,即使我使用了有效的证书,我在测试时也收到了“SSL连接错误”( CURLE_SSL_CONNECT_ERROR 35 )。 我的错误可能是我的libcurl特有的。

更新 :我在Windows 7上运行完全相同的东西,它完全按照需要工作。

 // using System.Net.Http; // using System.Security.Authentication; // using System.Security.Cryptography.X509Certificates; var handler = new HttpClientHandler(); handler.ClientCertificateOptions = ClientCertificateOption.Manual; handler.SslProtocols = SslProtocols.Tls12; handler.ClientCertificates.Add(new X509Certificate2("cert.crt")); var client = new HttpClient(handler); var result = client.GetAsync("https://apitest.startssl.com").GetAwaiter().GetResult(); 

我没有为我的客户端使用.Net,但是服务器端可以通过IIS部署我的Asp.Net Core网站,为IIS +客户端证书配置IIS,只需通过IIS进行配置:

iis客户端证书设置:

然后你可以在代码中简单地得到它:

  var clientCertificate = await HttpContext.Connection.GetClientCertificateAsync(); if(clientCertificate!=null) return new ContentResult() { Content = clientCertificate.Subject }; 

它对我来说很好,但我使用curl或chrome作为客户端,而不是.Net的。 在HTTPS握手期间,客户端从服务器获取请求以提供证书并将其发送到服务器。

事实上,如果您使用的是.Net Core客户端,它就不能拥有特定于平台的代码,如果它无法将自身连接到任何特定于操作系统的证书存储区,则将其解压缩并将其发送到服务器是有意义的。 如果您正在编译.Net 4.5.x,那么它似乎很简单:

https://pfelix.wordpress.com/2012/12/16/using-httpclient-with-ssltls/

就像编译curl一样,如果你想将它连接到Windows证书库,你必须针对某个特定的Windows库进行编译。

如果查看HttpClientHandler类的.NET Standard参考 ,可以看到ClientCertificates属性存在,但由于使用了EditorBrowsableState.Never而被隐藏。 这可以防止IntelliSense显示它,但仍然可以在使用它的代码中工作。

 [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public System.Security.Cryptography.X509Certificates.X509CertificateCollection ClientCertificates { get; }