Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient Certificate Errors

Can someone tell me why this throws an error about the certificate being invalid? In PowerShell, when I use the IP address in Invoke-WebRequest and set the host header to match the CN in the certificate, I do not get cert errors. I would assume that HttpClient would be the same?

var spHandler = new HttpClientHandler();
var spClient = new HttpClient(spHandler);
spClient.BaseAddress = new Uri("https://10.0.0.24");
var spRequest = new HttpRequestMessage(HttpMethod.Get, "/api/controller/");
spRequest.Headers.Host = "somehost.com";
var spResponse = await spClient.SendAsync(spRequest);

Errors:

WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
AuthenticationException: The remote certificate is invalid according to the validation procedure.

This code is part of a monitor utility, and we need to be able to probe each web front-end behind a load balancer. We do this a lot with PowerShell and I've never seen this issue as long as I set the Host header to match the certificate.

like image 631
Jed Avatar asked Sep 12 '25 15:09

Jed


2 Answers

The default behavior in HttpClient is to throw the error if there is any problem with the certificate.

If you want to bypass this behavior, you could change your code to that:

using var spHandler = new HttpClientHandler()
{
  ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
  {
    Console.WriteLine($"Sender: {sender}");
    Console.WriteLine($"cert: {cert}");
    Console.WriteLine($"chain: {chain}");
    Console.WriteLine($"sslPolicyErrors: {sslPolicyErrors}");
    return true;
  }
};

using var spClient = new HttpClient(spHandler);
spClient.BaseAddress = new Uri("https://10.0.0.24");
using var spRequest = new HttpRequestMessage(HttpMethod.Get, "/api/controller/");
spRequest.Headers.Host = "somehost.com";
using var spResponse = await spClient.SendAsync(spRequest);

All the Console.WriteLine stuff is just you to see the certificate info, you can delete that after you understand what is going on.

The return true is what bypass the certificate problem.

Be careful of using this in production, the best solution would be checking the certificate issues.

like image 174
mqueirozcorreia Avatar answered Sep 14 '25 05:09

mqueirozcorreia


You can also use DangerousAcceptAnyServerCertificateValidator:

HttpClientHandler httpClientHandler = new() { 
  ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
};
like image 28
kofifus Avatar answered Sep 14 '25 04:09

kofifus