即使没有 CA 匹配,也强制 ASP.NET WebAPI 客户端发送客户端证书 [英] Forcing ASP.NET WebAPI client to send a client certificate even when no CA match

查看:34
本文介绍了即使没有 CA 匹配,也强制 ASP.NET WebAPI 客户端发送客户端证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个特定的应用程序,它需要使用客户端证书来对 HTTPS 请求进行相互身份验证.服务器具有灵活的证书验证策略,允许它接受服务器证书存储中不存在的自签名客户端证书.众所周知,使用 curl 作为客户端可以很好地工作.

I have a specific application that requires the use of client certificates for mutual authentication of HTTPS requests. The server has a flexible certificate validation policy that allows it to accept self-signed client certificates that are not present in the server's certificate store. This is known to work just fine using curl as a client.

我通过测试和数据包嗅探确定的是,Microsoft 的 ASP.NET HttpClient 在 SSL 握手期间试图变得过于智能.如果此特定客户端具有到服务器的受信任根之一的信任链,则该特定客户端将仅使用客户端证书(来自 WebRequestHandler.ClientCertificates 集合).我观察到的是,如果没有具有信任链的证书,那么客户端在握手期间根本不会发送证书.

What I've determined via testing and packet sniffing is that Microsoft's ASP.NET HttpClient tries to be overly smart during the SSL handshake. This particular client will only use a client certificate (from the WebRequestHandler.ClientCertificates collection) if it has chain of trust to one of the server's trusted roots. What I've observed is that if there are no certificates with chain of trust then the client simply won't send a certificate at all during the handshake.

这是可以理解的默认行为,但过于严格,似乎无法将其关闭.我已经尝试了各种其他 WebRequestHandler 属性,包括 AuthenticationLevelClientCertificateOptions 但无济于事.

This is understandable default behavior but is overly restrictive and there appears to be no way to turn it off. I have experimented with various other WebRequestHandler properties, including AuthenticationLevel and ClientCertificateOptions but to no avail.

有没有办法强制 HttpClientClientCertificates 集合中可用时发送客户端证书,即使它看起来不会在服务器上验证边?我对直接和肮脏(反射黑客)解决方案都持开放态度,因为我真的需要这个客户端工作.

Is there a way to force HttpClient to send a client certificate when it is available in the ClientCertificates collection, even though it appears that it will not validate on the server side? I'm open to both straightforward and dirty (reflection hacks) solutions as I really need this client to work.

推荐答案

我认为您有多个证书或需要多个证书并需要附加它们.您可以向 X509CertificateCollection 添加尽可能多的证书.其中之一必须与 https 服务器证书匹配,否则您无法调用 Web 服务.

I think you have multiple certs or need multiple certs and need to attach them. you can add as many certs to X509CertificateCollection. One of them must match the https server cert otherwise you cant call web service.

try
    {
        X509Certificate2 clientCert = GetClientCertificate("cert1");
         X509Certificate2 clientCert = GetClientCertificate("cert2");
        X509Certificate2 clientCert = GetClientCertificate("cert3");
        WebRequestHandler requestHandler = new WebRequestHandler();
        requestHandler.ClientCertificates.Add(clientCert1);
         requestHandler.ClientCertificates.Add(clientCert2);

requestHandler.ClientCertificates.Add(clientCert3);HttpClient 客户端 = 新 HttpClient(requestHandler){BaseAddress = new Uri("http://localhost:3020/")};

requestHandler.ClientCertificates.Add(clientCert3); HttpClient client = new HttpClient(requestHandler) { BaseAddress = new Uri("http://localhost:3020/") };

        HttpResponseMessage response = client.GetAsync("customers").Result;
        response.EnsureSuccessStatusCode();
        string responseContent = response.Content.ReadAsStringAsync().Result;
        Console.WriteLine(responseContent);     
    }
    catch (Exception ex)
    {
        Console.WriteLine("Exception while executing the test code: {0}", ex.Message);
    }

然后调用这个请求.

private static X509Certificate2 GetClientCertificate( string probablerightcert)
{
    X509Store userCaStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    try
    {
        userCaStore.Open(OpenFlags.ReadOnly);
        X509Certificate2Collection certificatesInStore = userCaStore.Certificates;
        X509Certificate2Collection findResult = certificatesInStore.Find(X509FindType.FindBySubjectName, probablerightcert, true);
        X509Certificate2 clientCertificate = null;
        if (findResult.Count == 1)
        {
            clientCertificate = findResult[0];
        }
        else
        {
            throw new Exception("Unable to locate the correct client certificate.");
        }
        return clientCertificate;
    }
    catch
    {
        throw;
    }
    finally
    {
        userCaStore.Close();
    }
}

这篇关于即使没有 CA 匹配,也强制 ASP.NET WebAPI 客户端发送客户端证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆