【问题标题】:HttpClient does not send client certificate on Windows using .NET CoreHttpClient 不在使用 .NET Core 的 Windows 上发送客户端证书
【发布时间】:2017-12-04 10:38:54
【问题描述】:

我无法让 HttpClient 类在 Windows 上使用 .NET Core 发送客户端证书。

这是我正在使用的代码:

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();

代码在 Linux (Ubuntu 16.04) 上按预期工作(显然,证书路径已更改)。它不适用于 Windows。

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

我使用 .NET Framework 运行了类似的代码(使用“WebRequestHandler”而不是“HttpClientHandler”)。它正确发送客户端证书。

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

我还发现了this,这表明客户端证书确实适用于 Windows 上 .NET Core 上的 HttpClient。

我也尝试过明确设置 TLS 版本,但问题仍然存在。

我使用 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);
})

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

这是 .NET Core 中的错误吗?有解决办法吗?

【问题讨论】:

  • 是的,windows 和 linux 使用不同的处理程序(windows 上的 Winhttp,linux 上的 libcurl)。简要看一下 .net 核心代码,winhttp 处理程序似乎不支持客户端证书成员。您可以尝试使用 wip 托管处理程序。见:github.com/dotnet/corefx/blob/…

标签: c# .net asp.net-core .net-core kestrel-http-server


【解决方案1】:

不完全确定我重现此问题是否是由于相同的根本原因。但是,我遇到了同样的问题,结果证明没有发送证书,因为客户端无法验证它。在客户端上的“证书”MMC 管理单元中将颁发者证书添加到我的受信任颁发者列表后,Windows 可以验证证书并且 HttpClient 开始发送它。如果您有自签名证书,那么我假设您可以将其添加到受信任的颁发者存储中。这是在 .Net 4.6.1 上测试的。

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

【讨论】:

    猜你喜欢
    • 2018-05-27
    • 1970-01-01
    • 2014-04-07
    • 1970-01-01
    • 2022-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多