Search code examples
.netrestasp.net-coreauthentication

How to call a REST API from code, I only get AuthenticationException, UntrustedRoot


I am quite new to REST services, and I am trying to call a REST service from a colleague, secured only by Username and Password.

Using Postman everything is fine, I have a GET to the URL, I select "Basic Auth", set Username and Password and get the expected result.

Now I tried it via code: Calls to other websevices per code without user/pw work just fine, but here I just get an Exception:

public async Task<List<string>> MinimalProblemShowcase()
{
    string authenticationString = $"{clientId}:{clientSecret}"; // no typo, values are copy/pasted
    string base64EncodedAuthenticationString = Convert.ToBase64String(Encoding.UTF8.GetBytes(authenticationString));
    _client.DefaultRequestHeaders.Add("Authorization", "Basic " + base64EncodedAuthenticationString);

    try
    {
        var httpResponse = _client.GetAsync(Url).Result;

        // ToDo: evaluate httpResponse - but we don't get here...
    }
    catch (Exception ex)
    {
        // ...instead we drop here:
        // System.Net.Http.HttpRequestException: 
        // The SSL connection could not be established, see inner exception.
        // --->System.Security.Authentication.AuthenticationException: 
        // The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot
    }

    return [];
}

As indicated, I get

System.Net.Http.HttpRequestException: 
The SSL connection could not be established, see inner exception. 
---> System.Security.Authentication.AuthenticationException: 
    The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot

I am not aware of using certificates explicitely, but if so, it's on the same machine...

I suspect, it is just a minor detail I am missing, but what...? Thank you for any hint or help!


Solution

  • You could ignore the certificate untrusted issue by configure the httpclient

    var httpClientHandler = new HttpClientHandler();
    httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) =>{return true;};
    builder.Services.AddScoped<HttpClient>(sp => new HttpClient(httpClientHandler));
    

    Or you could do some validation with that certificate you are using.

    httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) => {
        if (cert.GetCertHashString() == "A7E2BA992F4F2BE220559B8A5371F05A00A6E750") //FingerPrint of the certificate
        {
            return true;
        }
        return false;
    };
    

    A standard way to solve this is you need to check if the Certificate Authority chains certs has been installed to windows. If they got correctly installed, you will needn't above settings. It should be valid when you run with visual studio.