HttpClient不使用。net Core在Windows上发送客户端证书

时间:2021-08-21 18:09:46

I am unable to get the HttpClient class to send a client certificate using .NET Core on Windows.

我无法让HttpClient类在Windows上使用. net内核发送客户机证书。

Here is the code I am using:

下面是我使用的代码:

X509Certificate2 certificate = new X509Certificate2(@"C:\Repos\selly\client1.pfx", "password");
HttpClientHandler handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ServerCertificateCustomValidationCallback = (a,b,c,d) => { return true; };
handler.ClientCertificates.Add(certificate);

HttpClient client = new HttpClient(handler);
var content = new StringContent("");
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
client.PostAsync("https://client2:5002/api/values", content).Wait();

The code works as expected on Linux (Ubuntu 16.04) (obviously, with the path to the certificate changed). It does not work on Windows.

这段代码在Linux (Ubuntu 16.04)上运行正常(显然,证书的路径改变了)。它不能在Windows上工作。

Looking at the exchange in Wireshark, the client does not send the certificate when running on Windows (10 v1703).

查看Wireshark中的交换,客户机在Windows上运行时不会发送证书(10 v1703)。

I have run similar code using .NET Framework (using 'WebRequestHandler' instead of 'HttpClientHandler'). It correctly sends the client certificate.

我使用。net框架运行类似的代码(使用“WebRequestHandler”而不是“HttpClientHandler”)。它正确地发送客户端证书。

I found the following online, but unlike the problem described there, the server certificate callback is executed. I did generate the certificates myself, but they are all signed by a Root CA, (which is installed on both client and server) and all the details are correct.

我在网上找到了以下内容,但是与上面描述的问题不同,服务器证书回调执行。我自己确实生成了证书,但是它们都是由根CA签名的(在客户机和服务器上都安装了),所有的细节都是正确的。

I also found this, which suggests that client certificates do work with HttpClient on .NET Core on Windows.

我还发现了这一点,这表明客户端证书可以在Windows上的。net Core上使用HttpClient。

I have also tried explicitly setting the TLS version, however the problem persists.

我还尝试过显式地设置TLS版本,但是问题仍然存在。

I am using Kestrel as the web server. It is configured as follows:

我正在使用Kestrel作为web服务器。配置如下:

.UseKestrel(options =>
{
    var sslOps = new HttpsConnectionFilterOptions();
    sslOps.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
    sslOps.ClientCertificateValidation = CheckClientCertificateLogic.CheckClientCertificate;
    sslOps.ServerCertificate = new X509Certificate2(@"C:\Repos\selly\client2.pfx", "password");
    options.UseHttps(sslOps);
})

The 'ClientCertificateValidation' callback does not execute on requests received from a Windows client; probably because it hasn't received a certificate for it to check...

“ClientCertificateValidation”回调不会执行从Windows客户端收到的请求;可能是因为它还没有收到要检查的证书……

Is this a bug in .NET Core? Is there a workaround?

这是。net核心中的一个bug吗?有解决方案吗?

1 个解决方案

#1


1  

Not entirely sure if my reproducing this issue is due to the same root cause. However, I had the same problem and it turns out that the certificate is not sent because the client cannot validate it. After adding the issuer certificate to my trusted issuers list in the "Certificates" MMC snap-in on the client, Windows can validate the certificate and HttpClient starts to send it. If you have a self-signed certificate then I assume that you can add that to the trusted issuers store instead. This was tested on .Net 4.6.1.

我不太确定我复制这个问题是否出于相同的根本原因。但是,我也遇到了同样的问题,因为客户端无法验证证书,所以没有发送证书。在客户机上的“证书”MMC管理单元中将发行者证书添加到我信任的发行者列表之后,Windows可以验证证书,HttpClient开始发送证书。如果您有一个自签名证书,那么我假设您可以将其添加到受信任的发行者存储中。这是在。net 4.6.1上测试的。

The relevant code that is setting the client certificate in WinHTTP is here. When you read code comments for GetEligibleClientCertificate, you see that MS has been planning to add additional filtering of the certificates that removes anything that isn't matched by the trusted issuers list. They simply haven't thought about the use case where you keep your certificate in a file and don't care about the certificate store.

在WinHTTP中设置客户端证书的相关代码在这里。当您阅读GetEligibleClientCertificate的代码注释时,您会看到MS一直计划添加对证书的额外过滤,以删除受信任发行者列表中不匹配的任何内容。他们根本没有考虑过您将证书保存在文件中的用例,也不关心证书存储。

#1


1  

Not entirely sure if my reproducing this issue is due to the same root cause. However, I had the same problem and it turns out that the certificate is not sent because the client cannot validate it. After adding the issuer certificate to my trusted issuers list in the "Certificates" MMC snap-in on the client, Windows can validate the certificate and HttpClient starts to send it. If you have a self-signed certificate then I assume that you can add that to the trusted issuers store instead. This was tested on .Net 4.6.1.

我不太确定我复制这个问题是否出于相同的根本原因。但是,我也遇到了同样的问题,因为客户端无法验证证书,所以没有发送证书。在客户机上的“证书”MMC管理单元中将发行者证书添加到我信任的发行者列表之后,Windows可以验证证书,HttpClient开始发送证书。如果您有一个自签名证书,那么我假设您可以将其添加到受信任的发行者存储中。这是在。net 4.6.1上测试的。

The relevant code that is setting the client certificate in WinHTTP is here. When you read code comments for GetEligibleClientCertificate, you see that MS has been planning to add additional filtering of the certificates that removes anything that isn't matched by the trusted issuers list. They simply haven't thought about the use case where you keep your certificate in a file and don't care about the certificate store.

在WinHTTP中设置客户端证书的相关代码在这里。当您阅读GetEligibleClientCertificate的代码注释时,您会看到MS一直计划添加对证书的额外过滤,以删除受信任发行者列表中不匹配的任何内容。他们根本没有考虑过您将证书保存在文件中的用例,也不关心证书存储。