在与HttpClient相同的位置访问HttpClientHandler

时间:2019-08-28 09:59:52

标签: .net-core dotnet-httpclient

我有一个请求URL并验证服务器SSL证书的服务。该代码已在完整的.NET框架中与HttpWebRequest一起顺利运行,但是现在我想将其迁移到HttpClient和.NET Core。我可以获得这样的证书(在多个博客文章和堆栈溢出答案中建议使用此方法):

X509Certificate2 cert = null;

var httpClient = new HttpClient(new HttpClientHandler
{
    ServerCertificateCustomValidationCallback = (request, certificate, chain, errors) =>
    {
        cert = certificate;
        return true;
    }
});

httpClient.GetAsync(...);

这里的问题是我不断创建新的HttpClient实例,不建议这样做。我想转到HttpClientFactory,为什么要在设置代码中添加以下内容:

services
    .AddHttpClient("sslclient", x =>
    {
        ...
    })
    .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
    {
        ServerCertificateCustomValidationCallback = (request, certificate, chain, errors) =>
        {
            return true;
        }
    });

现在的挑战是代码创建客户端不再具有对ServerCertificateCustomValidationCallback的访问权限:

var httpClient = httpClientFactory.CreateClient("sslclient");

有人知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

Reddit上的某人suggested使用以下解决方案。呼叫AddHttpClient之后,就无法再修改HttpClientHandler。可以共享资源,但是:

var certificates= new ConcurrentDictionary<string, X509Certificate2>();
services.AddSingleton(certificates);
services
    .AddHttpClient("sslclient", x =>
    {
        ...
    })
    .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
    {
        ServerCertificateCustomValidationCallback = (request, certificate, chain, errors) =>
        {
            certificates.TryAdd(request.RequestUri.Host, new X509Certificate2(certificate));
            return true;
        }
    });

在发出HTTP请求的代码中,您还需要注入certificates字典。提出请求后,您可以在字典中检查证书:

var response = await httpClient.GetAsync(url);
if (certificates.ContainsKey(uri.Host))
{
    // Happy days!
}