Asp.net web api 即使没有CA匹配,也强制ASP.NET WebAPI客户端发送客户端证书

Asp.net web api 即使没有CA匹配,也强制ASP.NET WebAPI客户端发送客户端证书,asp.net-web-api,.net-4.5,client-certificates,Asp.net Web Api,.net 4.5,Client Certificates,我有一个特定的应用程序,需要使用客户端证书对HTTPS请求进行相互身份验证。服务器具有灵活的证书验证策略,允许它接受服务器证书存储中不存在的自签名客户端证书。众所周知,使用curl作为客户机时,这种方法工作得很好 我通过测试和数据包嗅探确定,微软的ASP.NETHttpClient试图在SSL握手过程中过于智能。如果此特定客户端与服务器的一个受信任根具有信任链,则它将仅使用客户端证书(来自WebRequestHandler.ClientCertificates集合)。我观察到的是,如果没有具有信

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

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

这是可以理解的默认行为,但过于严格,似乎无法将其关闭。我尝试了各种其他
WebRequestHandler
属性,包括
AuthenticationLevel
ClientCertificateOptions
,但都没有用


当客户端证书在
ClientCertificates
集合中可用时,是否有办法强制
HttpClient
发送客户端证书,即使它似乎不会在服务器端验证?我对直截了当的和肮脏的(反射黑客)解决方案都持开放态度,因为我真的需要这个客户机来工作。

我也有同样的问题,同样没有运气。还观察到一种奇怪的行为,WebRequesthandler有时确实发送证书,这取决于线程/应用池凭据

我通过用RestClient替换HttpClient来解决这个问题。RestClient是开源的,可以通过nuget获得

API非常相似,在不抱怨证书的情况下实现了所需的魔力:

        var restClient = new RestClient($"{serviceBaseUrl}{requestUrl}");
        X509Certificate certificate = GetCertificateFromSomewhere();
        restClient.ClientCertificates = new X509CertificateCollection { certificate };
        var request = new RestRequest(Method.POST);
        request.RequestFormat = DataFormat.Json;
        request.AddParameter(new Parameter()
        {
            Type = ParameterType.RequestBody,
            Name = "Body",
            ContentType = "application/json",
            Value = "{your_json_body}"
        });

        IRestResponse<T> response = client.Execute<T>(request);
        if (response.ErrorException != null)
        {
            throw new Exception(response.Content, response.ErrorException);
        }
        return response.Data;
var restClient=new restClient($“{serviceBaseUrl}{requestUrl}”);
X509Certificate=GetCertificateFromSomewhere();
restClient.ClientCertificates=新X509CertificateCollection{certificate};
var请求=新的重新请求(Method.POST);
request.RequestFormat=DataFormat.Json;
request.AddParameter(新参数()
{
类型=ParameterType.RequestBody,
Name=“Body”,
ContentType=“application/json”,
Value=“{your_json_body}”
});
IRestResponse response=client.Execute(请求);
if(response.ErrorException!=null)
{
抛出新异常(response.Content、response.ErrorException);
}
返回响应数据;

我认为您有多个证书,或者需要多个证书并需要附加它们。 您可以向X509CertificateCollection添加任意数量的证书。 其中一个必须与https服务器证书匹配,否则无法调用web服务

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(“”) };

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

你找到解决这个问题的办法了吗?这个问题有什么想法吗?2018年,情况依然如此:(