4

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.

Jed
  • 51
  • 1
  • 5

3 Answers3

9

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:

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;
  }
};

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);

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.

mqueirozcorreia
  • 905
  • 14
  • 33
1

You can also use DangerousAcceptAnyServerCertificateValidator:

HttpClientHandler httpClientHandler = new() { 
  ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
};
kofifus
  • 17,260
  • 17
  • 99
  • 173
0

FIRST:
Clear c:\users<username>\AppData\Roaming\ASP.NET\Https folder

THEN From Powershell: dotnet dev-certs https --trust

Craig Wilcox
  • 1,577
  • 1
  • 12
  • 23