.net core HttpClientHandler未在.net核心中包含客户端证书

.net core HttpClientHandler未在.net核心中包含客户端证书,.net-core,certificate,httpclient,x509certificate,.net Core,Certificate,Httpclient,X509certificate,我在使用HttpClientHandler发送证书时遇到困难,因为该证书不会出现在服务器的请求中。该证书具有用于服务器和客户端身份验证的适当EKU,以及“数字签名”的密钥用法@davidsh认为这个问题是因为缺少HttpClient的日志记录,但在Visual Studio中运行我的项目(日志设置为跟踪并使用dotnet 3.1.401)时没有出现输出错误。我对logman一点也不熟悉,但在执行代码时,当问题应该发生时,我运行了logman,但日志中没有任何内容显示问题可能是什么。测试代码的选项

我在使用HttpClientHandler发送证书时遇到困难,因为该证书不会出现在服务器的请求中。该证书具有用于服务器和客户端身份验证的适当EKU,以及“数字签名”的密钥用法@davidsh认为这个问题是因为缺少HttpClient的日志记录,但在Visual Studio中运行我的项目(日志设置为跟踪并使用dotnet 3.1.401)时没有出现输出错误。我对logman一点也不熟悉,但在执行代码时,当问题应该发生时,我运行了logman,但日志中没有任何内容显示问题可能是什么。测试代码的选项不足我试图在客户端请求上添加一个没有私钥的证书,以查看
httpClientHandler.ClientCertificates.add…
是否会抛出任何错误,比如说“您需要一个带有私钥的证书来签署您的请求”,它不应该说什么吗

在客户端:

services.AddHttpClient<ILetterManClient, LetterManClient.LetterManClient>()
    .ConfigureHttpClient(client =>
    {
        client.BaseAddress = new Uri(configuration.GetValue<string>("Microservices:LetterManAPI"));
    })
    .ConfigurePrimaryHttpMessageHandler(() =>
    {
        HttpClientHandler httpClientHandler = new HttpClientHandler();

        httpClientHandler.ServerCertificateCustomValidationCallback = ValidateServiceCertficate;
        httpClientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;

        clientCertificate = new X509Certificate2("client_cert.pfx", "developer");

        httpClientHandler.ClientCertificates.Add(clientCertificate);

        return httpClientHandler;
    });
旁注: 我也一直在尝试使用从corefx repo编译的代码调试我的项目,以了解发生了什么,但Visual Studio坚持引用本地安装的sdk中的代码,而不是corefx中的项目,它正在引用它,但这是另一个问题

我创建了一个模拟问题的模型。它创建证书,并有两个项目,其中一个是服务,另一个是客户端

欢迎提供任何帮助。

是Kestrel需要客户端证书的指导原则,但它假设CA安装在机器中,否则在配置Kestrel服务器时,您必须直接指定客户端证书,如下所示:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
            webBuilder.ConfigureKestrel(o =>
            {
                o.ConfigureHttpsDefaults(o => {
                    o.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
                    o.ClientCertificateValidation = ValidateClientCertficate;
                });
            });
        });

public static Func<X509Certificate, X509Chain, SslPolicyErrors, bool> ValidateClientCertficate =
    delegate (X509Certificate serviceCertificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        X509Certificate2 clientCertificate;
        clientCertificate = new X509Certificate2("client.crt");

        if (serviceCertificate.GetCertHashString().Equals(clientCertificate.Thumbprint))
        {
            return true;
        }

        return false;
    };
公共静态IHostBuilder CreateHostBuilder(字符串[]args)=>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder=>
{
webBuilder.UseStartup();
webBuilder.ConfigureKestrel(o=>
{
o、 配置HttpSDEFULTS(o=>{
o、 ClientCertificateMode=ClientCertificateMode.RequireCertificate;
o、 ClientCertificateValidation=验证证书;
});
});
});
公共静态函数ValidateClient证书=
委托(X509Certificate-serviceCertificate、X509Chain-chain、SslPolicyErrors SslPolicyErrors)
{
X509Certificate2客户证书;
clientCertificate=新的X509Certificate2(“client.crt”);
if(serviceCertificate.GetCertHashString().Equals(clientCertificate.Thumbprint))
{
返回true;
}
返回false;
};
不幸的是,您不能像我所期望的那样要求特定路由的客户端证书。

是Kestrel要求客户端证书的指导原则,但它假设CA安装在机器中,否则您必须在配置Kestrel服务器时直接指定客户端证书,如下所示:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
            webBuilder.ConfigureKestrel(o =>
            {
                o.ConfigureHttpsDefaults(o => {
                    o.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
                    o.ClientCertificateValidation = ValidateClientCertficate;
                });
            });
        });

public static Func<X509Certificate, X509Chain, SslPolicyErrors, bool> ValidateClientCertficate =
    delegate (X509Certificate serviceCertificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        X509Certificate2 clientCertificate;
        clientCertificate = new X509Certificate2("client.crt");

        if (serviceCertificate.GetCertHashString().Equals(clientCertificate.Thumbprint))
        {
            return true;
        }

        return false;
    };
公共静态IHostBuilder CreateHostBuilder(字符串[]args)=>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder=>
{
webBuilder.UseStartup();
webBuilder.ConfigureKestrel(o=>
{
o、 配置HttpSDEFULTS(o=>{
o、 ClientCertificateMode=ClientCertificateMode.RequireCertificate;
o、 ClientCertificateValidation=验证证书;
});
});
});
公共静态函数ValidateClient证书=
委托(X509Certificate-serviceCertificate、X509Chain-chain、SslPolicyErrors SslPolicyErrors)
{
X509Certificate2客户证书;
clientCertificate=新的X509Certificate2(“client.crt”);
if(serviceCertificate.GetCertHashString().Equals(clientCertificate.Thumbprint))
{
返回true;
}
返回false;
};
不幸的是,您不能像我预期的那样要求特定路由的客户端证书