1

We're trying to communicate with an API of ours which needs a certificate in the request but it doesn't work well.

Usually we used an external service or an Azure API Management API just by passing a SubscriptionKey in the request headers, but this time we have a certificate (.cer) that we need to inject in the AndroidHttpClientHandler but this feature doesn't seem to be supported, or maybe we're using it wrong ?

Do you know if this scenario is truly possible and if yes, how we should achieve it ? I tried many things such as create a custom AndroidHttpClientHandler to allow putting a ClientCertificate in it but without success

2
  • Do you used public certificate or private certificate(self-certificate)?If you used the private certifcates, you will meet javax.net.ssl.SSLException: Not trusted server certificate exception.I do not know which specific features did you want to acheved, If you want to connect server by SSL, it could be acheved.devblogs.microsoft.com/xamarin/… Commented Apr 17, 2019 at 7:12
  • Well what we tried so far didn't work because when we wanted to use the classic WebRequestHandler it didn't work because an exception was thrown "NotImplementedException" --> our project is still a PCL (targeting .NET 4.5) Commented Apr 19, 2019 at 13:20

1 Answer 1

3

Finally managed to get it work :D For those who are interested, here's how I achieve it :

TL;DR: Upgrade to Visual Studio 2019 and HttpWebRequest comes to the rescue (you can find the code sample below) ;-)

Context: our project consists of a PCL and a Android project. In the team, we know we have to migrate the PCL to a .NET Standard project but it takes time, especially when you have a lot of librairies to deal with (libraries that are not updated to .NET Standard) xP

  • When you want to call an API, the first thing that comes to your mind is to use the HttpClient/HttpRequestHandler pair where we just have to pass our certificate in the HttpRequestHandler as follows :

    httpRequestHandler.ClientCertificates.Add(new X509Certificate2(..))

Why it didn't work ? Because we're developing with Xamarin.Android which uses under the hood Mono.Droid, therefore we're meeting the unpopular NotImplementedException() ! What about WebRequestHandler ? Well the same fate :P

Hopefully the salvation came from HttpWebRequest as follows :

        private Task<string> ExecuteRequest(Uri uri, X509Certificate2 certificate)
        {
            // Create a web request that points to our secured Backend API
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);

            if (certificate != null)
            {
                // Associate the certificates with the request
                request.ClientCertificates.Add(certificate);
            }

            // Launch the web request
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            // Output the stream to a jsonTextReader or anything else depending on your needs
            using (Stream stream = response.GetResponseStream())
            using (StreamReader sr = new StreamReader(stream))
            using (var jsonTextReader = new JsonTextReader(sr))
            {
                // Do whatever you want
            }
        }

This code worked on my machine (Visual Studio 2019) but not on my colleague (Visual Studio 2017) : indeed the following exception was met :

System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception.

I also have VS2017 installed on my machine so I've tried to execute the same code with it and as strange as it sounds, I also got the error

Et voilà :) Of course, the certificate had to be "an Embedded resource"

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.