I'm rewriting some web handling code in WinForms and switching from HttpWebRequest to HttpClient. There's one last thing I require that I cannot seem to find out how to accomplish.
In HttpWebRequest, I can capture the certificate from the web server I'm connecting to and display it:
...
HttpWebRequest request = CreateHttpRequest(destUri);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
cert = request.ServicePoint.Certificate;
if (cert != null) 
{ 
  cert2 = new X509Certificate2(cert); 
  X509Certificate2UI.DisplayCertificate(cert2);
}
...
I cannot find the equivalent way capture the certificate using HttpClient:
//... Use HttpClient.
using (HttpClient client = new HttpClient())
{
  using (HttpResponseMessage response = await client.GetAsync(destUri))
  {
    using (HttpContent content = response.Content)
    {
      string result = await content.ReadAsStringAsync();
    }
  }
}
How/where can I do this here? I don't know how to get to the ServicePoint.Certificate.
Apparently, you don't need to get the certificate from the ServicePointManager.ServerCertificateValidationCallback. You can find it from ServicepointManager itself, like so:
//... Use HttpClient.
using (HttpClient client = new HttpClient())
{
  using (HttpResponseMessage response = await client.GetAsync(destUri))
  {
    // Get Certificate Here
    var cert = ServicePointManager.FindServicePoint(destUri).Certificate;
    //
    using (HttpContent content = response.Content)
    {
      string result = await content.ReadAsStringAsync();
    }
  }
}
                        Bulding on Remus answer - here is something I've cobbled up in LinqPad, which does give you access to your certificate:
var handler = new WebRequestHandler();
handler.UseDefaultCredentials = true;
handler.AllowPipelining = true;
handler.ServerCertificateValidationCallback =  (sender, cert, chain, error) => {
    //do something with cert here
    cert.Subject.Dump();
    //useless validation on my part
    return true;
};
using (HttpClient client = new HttpClient(handler))
{
  using (HttpResponseMessage response = await client.GetAsync("https://google.com"))
  {
    using (HttpContent content = response.Content)
    {
        //foo
    }
  }
}
Dump() the outputs the following:
CN=*.google.com, O=Google Inc, L=Mountain View, S=California, C=US
CN=www.google.de, O=Google Inc, L=Mountain View, S=California, C=US
CN=www.google.com, O=Google Inc, L=Mountain View, S=California, C=US
Use a WebRequestHandler with a proper certificate validation callback. see HttpClient, HttpClientHandler, and WebRequestHandler Explained for example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With