Проблема Xamarin Android при подключении через HTTPS к сайту с самозаверяющим сертификатом: «Не найдена доверенная привязка для пути сертификации». - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь сделать HTTPS-вызовы на сайт, имеющий 2 SSL-сертификата: самозаверяющий сертификат и сертификат, подписанный первым сертификатом.Когда я использую HttpClient для отправки запроса на сайт, консоль регистрирует ненадежную цепочку, показывает оба сертификата, а затем распечатывает длинную трассировку стека, вызванную java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

Я установил оба сертификатана моем телефоне и переходе Chrome на сайт показывает доверенное соединение (у него было предупреждение о недоверенном соединении, прежде чем я установил сертификаты).Я считаю, что проблема в том, что приложение отказывается доверять самозаверяющим сертификатам.У меня нет доступа к серверу, и поэтому я не могу влиять на его сертификаты, поэтому установка сертификата, подписанного доверенным центром сертификации, невозможна.


Решения, которые я пробовал, но не работали.

ServicePointManager.ServerCertificateValidationCallback не работает.

Я пытался использовать свою собственную функцию для ServicePointManager.ServerCertificateValidationCallback, но делегат, который я ей предоставляю, никогда не запускается.У меня есть следующий код в моем методе MainActivity.OnCreate, но консоль никогда не регистрирует сообщение:

System.Net.ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
  Console.WriteLine($"****************************************************************************************************");

  return true;
};

HttpClientHandler.ServerCertificateCustomValidationCallback вызывает исключение.

У меня естьпопытался использовать HttpClientHandler и настройки ServerCertificateCustomValidationCallback, но я просто получаю сообщение:

System.NotImplementedException: The method or operation is not implemented. at System.Net.Http.HttpClientHandler.set_ServerCertificateCustomValidationCallback (System.Func`5[T1,T2,T3,T4,TResult] value).

Код настройки:

HttpClientHandler handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
HttpClient client = new HttpClient(handler);

1 Ответ

0 голосов
/ 11 марта 2019

Мне удалось заставить это работать как на Android, так и на iOS.

iOS было легко, просто переопределить ServicePointManager.ServerCertificateValidationCallback:

ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

Для Android Я использовал Ответ Бруно Касейро на аналогичный вопрос и созданную службу зависимостей.

В моем проекте Xamarin Forms я добавил простой интерфейс:

public interface IHTTPClientHandlerCreationService
{
  HttpClientHandler GetInsecureHandler();
}

И в моем проекте Xamarin для Android я реализовал интерфейс:

[assembly: Dependency(typeof(HTTPClientHandlerCreationService_Android))]
namespace MyApp.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;
    }
  }
}

Общий код для правильной настройки HttpClient:

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...