1

I'm learning how API requests work. As part of my learning I am writing a simple app for myself that connects to my company's main app/server through its REST API.

I have some experience with C# and I sort of understand how TCP handshakes work at a very basic level. I have searched through Google and Microsoft's documentation on how to do this and, after seeing so many ways on how people do it differently, I'm at the end of my patience with it.

What I want to do:

  1. Connect to Server
  2. Send API Key to authenticate (I have set my server to enable REST clients with no client certificate)
  3. Get the 'Cardholder' JSON information from the server
  4. Print the information to the Console.

I'm running the server locally and connect with my 'client' app through port 8904.

When I run my current script in Visual Studio I get an Exception Unhandled error that says: "System.Net.Http.HttpRequestException: 'The SSL connection could not be established, see inner exception... Inner Exception: AuthenticationException: The remote certificate is invalid according to the validation procedure: RemoteCertificateNameMismatch, RemoteCertificateChainErrors

I've tried Googling how to get around this error, which brought me to adding the 'ServicePointManager.ServerCertificateValidationCallback' lines, but they seem to make no difference to the outcome.

Here's my code.

static void Main(string[] args)
{
    ConnectToAPI();
}

public static void ConnectToAPI ()
{
    var client = new HttpClient();

    var webRequest = new HttpRequestMessage(HttpMethod.Get, "https://127.0.0.1:8904/api/cardholders");

    webRequest.Headers.Add(HttpRequestHeader.Authorization.ToString(), "XXXX-XXXX-XXXX-MY-API-KEY-GOES-HERE");

    ServicePointManager.ServerCertificateValidationCallback +=
    (sender, certificate, chain, errors) => {
            return true;
        };

    var response = client.Send(webRequest);

    using var reader = new StreamReader(webRequest.Content.ReadAsStream());

    Console.WriteLine(reader.ReadToEnd());
    Console.ReadLine();
}
John Smith
  • 11
  • 3

1 Answers1

0

I don't know why I was getting this error.

I seemed to be able to avoid the error by changing my code around to this (see below).

If anyone finds this and can explain why it now works you'll help me understand why and hopefully someone else in the future too :P

static void Main(string[] args)
        {
            ConnectToAPI();
            Console.ReadLine();
        }

public static void ConnectToAPI ()
        {
            // Creates the WebRequest object using the uri string
            string uri = String.Format("https://127.0.0.1:8904/api/cardholders");
            WebRequest requestObjGet = WebRequest.Create(uri);            

            // Adds API key as a header to the request. Note, must also append 'GGL-API-KEY' to the start
            requestObjGet.Headers.Add(HttpRequestHeader.Authorization.ToString(), "XXXX-XXXX-XXXX-MY-API-KEY-GOES-HERE");

            // Allows you to bypass "AuthenticationException: The remote certificate is invalid according to the validation procedure." error. Don't to do this in production code...
            ServicePointManager.ServerCertificateValidationCallback = delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {return true;};

            requestObjGet.Method = "GET";
            HttpWebResponse responseObjGet = null;
            responseObjGet = (HttpWebResponse)requestObjGet.GetResponse();

            // String to hold API request response data
            string strresulttest = null;

            // Stream reads data to string and prints it to console
            using (Stream stream = responseObjGet.GetResponseStream())
            {
                StreamReader sr = new StreamReader(stream);
                strresulttest = sr.ReadToEnd();
                Console.WriteLine(strresulttest);
                sr.Close();
            }
        }

John Smith
  • 11
  • 3
  • Error is caused by invalid server certificate. Error is gone because you added line that completely disables server certificate validation, with is bad practice for security reasons. – Dzliera Jul 01 '21 at 23:04
  • 1
    By any chance, do you have any proxy debugger like Fiddler or Charles running when testing this code? because such kind of proxies inject fake certificate in connection and cause security check to fail. – Dzliera Jul 01 '21 at 23:05
  • @John Smith Have a look a this thread: https://stackoverflow.com/questions/12553277/allowing-untrusted-ssl-certificates-with-httpclient – SimonD Dec 16 '22 at 10:22