HttpClient与客户端证书一起重用
本文关键字:一起 证书 客户端 HttpClient | 更新日期: 2023-09-27 18:05:36
我在几个地方读到(如这里,这里或这里),这是一个坏的做法,在请求后直接处理HttpClient,最好在所有请求完成后处理它,以允许重用连接。
为了尝试,我创建了一个HttpClient实例,并以这种方式添加到类中的静态字段:
public class Test
{
private static X509Certificate2 _certificate;
private static HttpClient HttpClient { get; set; }
...
public Test()
{
...
if (HttpClient == null)
{
LoadCertificate();
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;
var handler = new WebRequestHandler();
handler.ClientCertificates.Add(_certificate);
HttpClient = new HttpClient(handler, false);
}
}
private void LoadCertificate()
{
using (var store = new X509Store(StoreName.My, CertificateStoreLocation))
{
store.Open(OpenFlags.ReadOnly);
var certificates = store.Certificates.Find(X509FindType.FindBySubjectName, CertificateFriendlyName, true);
if (certificates.Count != 1)
throw new ArgumentException(
$"Cannot find a valid certificate with name {CertificateFriendlyName} in {CertificateStoreLocation}");
_certificate = certificates[0];
store.Close();
}
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
}
}
然后使用我的实例通过以下命令调用web服务:
var result = await HttpClient.PostAsJsonAsync(completeUri, request);
我第一次运行代码,一切正常,我得到一个正确的响应,但随后,所有的时间我从服务器得到一个未经授权的告诉我,我没有使用客户端证书。
这就像在接下来的呼叫中,没有考虑到WebRequestHandler
。
你的修复应该是这样的:
handler.PreAuthenticate = true;
一旦您建立了到服务的连接,您就可以使用具有不同认证信息的不同客户端重用它来与它通信。这意味着,服务需要知道每次发送请求的是哪个客户端,否则可能是安全漏洞——例如,在最后连接的客户端下执行请求。这取决于您的身份验证机制,但基本上WebRequestHandler
在第一次请求后设置标志IsAuthenticated
,并在下一次请求时停止发送验证信息。PreAuthenticate
选项强制在每个请求上发送验证信息。