C# 如何使用.Net Core中的单个HttpClient实例在不同请求上发送不同的客户端证书?

C# 如何使用.Net Core中的单个HttpClient实例在不同请求上发送不同的客户端证书?,c#,.net,asp.net-core,.net-core,dotnet-httpclient,C#,.net,Asp.net Core,.net Core,Dotnet Httpclient,建议使用HttpClient。但从API来看,添加证书的方式似乎是在实例上,而不是每个请求。例如,如果我们添加两个证书,如何确保“cert 1”只发送到“one.somedomain.com” //处理程序是如何添加客户端证书的(还有其他方法吗?) var_clientHandler=新的HttpClientHandler(); //添加多个证书 _clientHandler.ClientCertificates.Add(cert1); _clientHandler.ClientCertific

建议使用
HttpClient
。但从API来看,添加证书的方式似乎是在实例上,而不是每个请求。例如,如果我们添加两个证书,如何确保“cert 1”只发送到“one.somedomain.com”

//处理程序是如何添加客户端证书的(还有其他方法吗?)
var_clientHandler=新的HttpClientHandler();
//添加多个证书
_clientHandler.ClientCertificates.Add(cert1);
_clientHandler.ClientCertificates.Add(cert2);
_clientHandler.ClientCertificateOptions=ClientCertificateOptions.Manual;
//假设这是我们长寿的HttpClient
var client=新的HttpClient(_clientHandler);
//现在如果我们发出post请求,两个证书都会被使用吗?
使用(HttpResponseMessage响应=_client.PostAsync(“https://one.somedomain.com“,内容)。结果)
{
//…省略。。。
}

这是建议,但是,您可以使用“using”语句

一旦HttpClient成为IDisposable,您应该使用

using(var client = new HttpClient(_clientHandler))
{
    //Your code here
}

对不起。年底有很多工作要做。 您可以尝试实现如下内容:

public class CustomHttpHandler : HttpClientHandler
{
    private readonly Dictionary<string, X509Certificate> _certMap;

    public CustomHttpHandler():base()
    {
        _certMap = new Dictionary<string, X509Certificate>() { { "server1name", new X509Certificate("cert1") }, { "server2name", new X509Certificate("cert2") } };
    }

    protected override async Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request,
            CancellationToken cancellationToken)
    {
        string serverName = request.RequestUri.Host;
        if (ClientCertificates.Contains(_certMap[serverName]))
        {
            try
            {
                var response = await base.SendAsync(request, cancellationToken);
                return response;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadKey();
                throw;
            }
        }
        else
        {
            ClientCertificates.Clear();
            ClientCertificates.Add(_certMap[serverName]);

            try
            {
                var response = await base.SendAsync(request, cancellationToken);
                return response;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadKey();
                throw;
            }
        }
    }
}
公共类CustomHttpHandler:HttpClientHandler
{
专用只读词典_certMap;
公共CustomHttpHandler():base()
{
_certMap=new Dictionary(){{“server1name”,new X509Certificate(“cert1”)},{“server2name”,new X509Certificate(“cert2”)};
}
受保护的覆盖异步任务SendAsync(
HttpRequestMessage请求,
取消令牌(取消令牌)
{
字符串serverName=request.RequestUri.Host;
if(ClientCertificates.Contains(_certMap[serverName]))
{
尝试
{
var response=await base.sendaync(请求、取消令牌);
返回响应;
}
捕获(例外情况除外)
{
控制台写入线(例如消息);
Console.ReadKey();
投掷;
}
}
其他的
{
ClientCertificates.Clear();
ClientCertificates.Add(_certMap[serverName]);
尝试
{
var response=await base.sendaync(请求、取消令牌);
返回响应;
}
捕获(例外情况除外)
{
控制台写入线(例如消息);
Console.ReadKey();
投掷;
}
}
}
}
只是一个想法,而不是测试它。 或者,您也可以在
RequestMessage
实例中使用
Headers
集合。
本文讨论的主题是:

看来,您需要实现自己的
HttpClientHandler
,并具有可终止的行为。我认为为每台服务器创建新的HttpClient可以节省时间。您可以将它们放在一个字典中,其中密钥是server baseaddress@KrivitskiyGrigoriy这可能是唯一的选择,但我想知道这是否会在每个请求上增加太多额外的处理,或者是否有办法保持速度?另外,您知道如何执行此操作吗?Microsoft特别不建议这样做,这会导致性能问题、内存泄漏和连接句柄泄漏。在退出之前,是否有任何方法可以处理字典值。