Xamarin: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found

Viewed 5893

In Xamarin. I've been trying to make communications between my Web API and my Xamarin project. Here's the code for my controller:

//  GET api/values
    public List<string> Get()
    {
        List<string> values = new List<string>();
        values.Add("Value 1");
        values.Add("Value 2");
        return values;
    }

And here is my GET request in my MainPage.xaml.cs

    public async void BindToListView()
    {
        HttpClient client = new HttpClient();
        var response = await client.GetStringAsync("https://10.0.2.2:#####/api/Values");
        var posts = JsonConvert.DeserializeObject<List<Posts>>(response);
        lv.ItemsSource = posts;
    }

Whenever I try to run both my Android application and my Web API Application. I keep getting this exception:

    Javax.Net.Ssl.SSLHandshakeException: 
'java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.'

I've tried pasting this into my MainActivity.cs, but it still doesn't work.

ServicePointManager.ServerCertificateValidationCallback += (o, cert, chain, errors) => true;

I've been having this problem for months now, and its driving me crazy. Am I missing something? I'm fairly new in developing Xamarin applications, and this is a problem that I can't seem to resolve.

Any suggestions on how to resolve this problem will be greatly appreciated. Thanks for taking the time in reading this.

2 Answers
//Use this, it worked for me. 

HttpClient client;

public class datastore {
   var httpClientHandler = new HttpClientHandler();
            
   httpClientHandler.ServerCertificateCustomValidationCallback = 
   (message, cert, chain, errors) => { return true; };

   client = new HttpClient(httpClientHandler);
}

//... use the client to make request. it will bypass 
//the ssl certificates verification. 

For Android you should do something more .

in Forms ,create an interface

public interface IHTTPClientHandlerCreationService
{
  HttpClientHandler GetInsecureHandler();
}

in Android implemented the interface:

[assembly: Dependency(typeof(HTTPClientHandlerCreationService_Android))]
namespace xxx.Droid
{
  public class HTTPClientHandlerCreationService_Android : CollateralUploader.Services.IHTTPClientHandlerCreationService
  {
    public HttpClientHandler GetInsecureHandler()
    {
      return new IgnoreSSLClientHandler();
    }
  }

  internal class IgnoreSSLClientHandler : AndroidClientHandler
  {
    protected override SSLSocketFactory ConfigureCustomSSLSocketFactory(HttpsURLConnection connection)
    {
      return SSLCertificateSocketFactory.GetInsecure(1000, null);
    }

    protected override IHostnameVerifier GetSSLHostnameVerifier(HttpsURLConnection connection)
    {
      return new IgnoreSSLHostnameVerifier();
    }
  }

  internal class IgnoreSSLHostnameVerifier : Java.Lang.Object, IHostnameVerifier
  {
    public bool Verify(string hostname, ISSLSession session)
    {
      return true;
    }
  }
}

And when you call the method Get

public async void BindToListView()
{
  HttpClient client;

  switch (Device.RuntimePlatform)
  {
    case Device.Android:
      this.httpClient = new HttpClient(DependencyService.Get<Services.IHTTPClientHandlerCreationService>().GetInsecureHandler());
      break;
    default:
      ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
      this.httpClient = new HttpClient(new HttpClientHandler());
      break;
  }

  var response = await client.GetStringAsync("https://10.0.2.2:#####/api/Values");
  var posts = JsonConvert.DeserializeObject<ObservableCollection<Posts>>(response);
  lv.ItemsSource = posts;
}

In addition, I suggest that you can use ObservableCollection instead of List because it has implemented the interface INotifyPropertyChanged . Otherwise the UI will never been updated .

Related