我有一个请求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");
有人知道如何解决这个问题吗?
答案 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!
}