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

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

问题描述

我有一个特定的应用程序,该应用程序需要使用客户端证书来对HTTPS请求进行相互身份验证。该服务器具有灵活的证书验证策略,该策略允许它接受服务器证书存储中不存在的自签名客户端证书。

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.

我通过测试和数据包嗅探确定,微软的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 属性,包括 AuthenticationLevel ClientCertificateOptions 但无济于事。

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.

是否有一种方法可以强制 HttpClient 在其发送客户端证书可以在 ClientCertificates 集合中找到,即使它似乎无法在服务器端进行验证?我对简单和肮脏的(反思性黑客)解决方案都持开放态度,因为我确实需要此客户端才能工作。

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 =新的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天全站免登陆