.NET6下RestSharp携带SSL证书请求报TLS HandshakeFailure异常
问题根因
- RestSharp 108.0.1版本基于
HttpClient封装,内部的HttpClientHandler会在RestClient构造阶段完成初始化。你当前代码是先构造RestClient实例,再给client.Options.ClientCertificates赋值证书集合,这个赋值操作不会同步到已经初始化完成的HttpClientHandler上,实际发起请求时handler根本没有携带你加载的客户端证书,服务端在TLS握手阶段校验不到合法客户端证书,直接返回握手失败告警。 - 你写的原生
HttpClient代码能正常运行,是因为你先完成了handler的证书配置,再用配置好的handler初始化HttpClient,证书配置全程生效。 - 额外说明:你尝试设置的
System.Net.ServicePointManager.SecurityProtocol是.NET Framework时代的遗留配置,在.NET 6运行时下不会对HttpClient的TLS版本选择生效,加这段代码解决不了当前问题。
修复方案
选择以下任意一种写法调整代码即可:
方案1:在ConfigureMessageHandler委托内完成证书配置
不要在RestClient构造完成后再赋值证书,直接在handler初始化的委托里把证书、TLS版本都配置完成:
async Task WithRestSharp() { RestResponse? result = null; try { var certificate = GetCertificate(); var options = new RestClientOptions("你的目标接口基地址") { ConfigureMessageHandler = handler => { if (handler is not HttpClientHandler clientHandler) return handler; clientHandler.SslProtocols = SslProtocols.Tls12; // 直接在handler初始化阶段添加证书 clientHandler.ClientCertificates.Add(certificate); return clientHandler; } }; var client = new RestClient(options); var request = new RestRequest("你的请求路径"); result = await client.ExecuteGetAsync(request); if (result.ErrorException is not null) throw result.ErrorException; Console.WriteLine("Status Code: {0}", result.StatusCode); } catch (Exception e) { Console.WriteLine("Status Code: {0}", result?.StatusCode); Console.WriteLine(e.ToString()); } }
方案2:初始化RestClientOptions时提前配置好证书集合
在构造RestClient之前,就把证书集合赋值给Options的ClientCertificates属性,保证RestClient构造handler时能读取到证书配置:
async Task WithRestSharp() { RestResponse? result = null; try { var certificate = GetCertificate(); var options = new RestClientOptions("你的目标接口基地址") { // 提前给Options配置证书 ClientCertificates = new X509CertificateCollection { certificate }, ConfigureMessageHandler = handler => { if (handler is not HttpClientHandler clientHandler) return handler; clientHandler.SslProtocols = SslProtocols.Tls12; return clientHandler; } }; // 用配置完成的options初始化client,之后不要修改Options里的证书配置 var client = new RestClient(options); var request = new RestRequest("你的请求路径"); result = await client.ExecuteGetAsync(request); if (result.ErrorException is not null) throw result.ErrorException; Console.WriteLine("Status Code: {0}", result.StatusCode); } catch (Exception e) { Console.WriteLine("Status Code: {0}", result?.StatusCode); Console.WriteLine(e.ToString()); } }
内容的提问来源于stack exchange,提问作者Ayrton Guttier
相关产品推荐
相关产品推荐

