Игнорировать ошибки сертификата SSL в Xamarin.Forms (PCL)

Есть ли способ сделать что-то, как описано здесь: /questions/31773144/c-ignorirovat-oshibki-sertifikata/31773150#31773150 но в приложении Xamarin.Forms PCL? Я использую HttpClient для подключения к серверу.

6 ответов

ServicePointManager не определено в PCL, но определено в платформо-зависимых классах.

Есть ServicePointManager в Xamarin.iOS и Xamarin.Android с одинаковым использованием. Вы можете ссылаться на него внутри любых классов в проектах вашей платформы. Однако в настоящее время такого класса нет и, похоже, нет способа сделать это для приложения Windows Phone.

Пример:

// Xamarin.Android

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        // You may use ServicePointManager here
        ServicePointManager
            .ServerCertificateValidationCallback +=
            (sender, cert, chain, sslPolicyErrors) => true;

        base.OnCreate(bundle);

        global::Xamarin.Forms.Forms.Init(this, bundle);
        LoadApplication(new App());
    }
}

// Xamarin.iOS

public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        ServicePointManager
            .ServerCertificateValidationCallback +=
            (sender, cert, chain, sslPolicyErrors) => true;

        global::Xamarin.Forms.Forms.Init();
        LoadApplication(new App());

        return base.FinishedLaunching(app, options);
    }
}

Используя уникальный код в Xamarin.Forms, создайте экземпляр HttpClientHandler.Пример:

private HttpClient _httpClient;
public HttpClient HttplicentAccount
{
    get
    {
        _httpClient = _httpClient ?? new HttpClient
        (
            new HttpClientHandler()
            {
                ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
                {
                    //bypass
                    return true;
                },
            }
            , false
        )
        {
            BaseAddress = new Uri("YOUR_API_BASE_ADDRESS"),
        };

        // In case you need to send an auth token...
        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", "YOUR_TOKEN");
        return _httpClient;
    }
}

Если вы используете AndroidClientHandlerВам необходимо предоставить SSLSocketFactory и пользовательская реализация HostnameVerifier все проверки отключены. Для этого вам нужно будет создать подкласс AndroidClientHandler и переопределить соответствующие методы.

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

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

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

А потом

var handler = new BypassSslValidationClientHandler();
var httpClient = new System.Net.Http.HttpClient(handler);
      public static HttpClient PreparedClient() {
 HttpClientHandler handler = new HttpClientHandler();
 handler.ServerCertificateCustomValidationCallback+= (sender, cert, chain,sslPolicyErrors) => { return true; }; 
 HttpClient client = new HttpClient(handler); return client; 
}

HttpClient client = PreparedClient();

Я столкнулся с этим, но с немного другим сообщением об ошибке:

Ssl error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED
  at /Users/builder/jenkins/workspace/archive-mono/2019-02/android/release/external/boringssl/ssl/handshake_client.c:1132

Я исправил это следующим образом в OnCreate (MainActivity.cs):

protected override void OnCreate(Bundle savedInstanceState)
{
    TabLayoutResource = Resource.Layout.Tabbar;
    ToolbarResource = Resource.Layout.Toolbar;

    base.OnCreate(savedInstanceState);

// HERE
#if DEBUG
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
#endif

    Xamarin.Essentials.Platform.Init(this, savedInstanceState);
    Forms.Init(this, savedInstanceState);

    // Initialize Material Design renderer
    FormsMaterial.Init(this, savedInstanceState);


    LoadApplication(new App());
}

Это было исправление для Android, добавив тот же код в FinishedLaunching (AppDelegate.cs) для iOS тоже должно работать.

  • Поместите эту строку кода внутри OnCreate в MainActivity.cs: System.Net.ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

это должно быть так:

protected override void OnCreate(Bundle savedInstanceState)
        {

            // to bypass ssl
            System.Net.ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
            ...
            ..
            LoadApplication(new App());
        }
  • Теперь измените var httpClient = new HttpClient();

  • кому: var httpClient = new HttpClient(новый System.Net.Http.HttpClientHandler());

  • И не забудьте называть IP-адрес вместо использования localhost

Другие вопросы по тегам