在Xamarin.Forms(PCL)中忽略SSL证书错误

30
6个回答

35

ServicePointManager在PCL中未定义,但在特定于平台的类中定义。

Xamarin.iOSXamarin.Android均具有相同用法的ServicePointManager。您可以在平台项目中的任何类中引用它。然而,目前不存在这样的类,并且似乎没有办法为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);
    }
}

2
这对我不起作用。回调从未被调用,并生成了一个说 SSL 无效的异常。 - DaveEP
2
AndroidClientHandler似乎不支持ServerCertificateValidationCallback。您有任何更新的信息来处理Android上的这个问题吗? - Klatschen
18
这个解决方案不适用于 Android。 - Abdurakhmon

25

使用 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;
    }
}

2
在这里提供的所有解决方案中,这个可以在最新的2019/20更新后,在VS2019上为Android工作。 - TheLegendaryCopyCoder
在应用了上述代码之后仍然得到相同的错误。 - parpar
1
这对我在最新更新的VS2022上为Android工作。我非常感激。我已经在这个问题上工作了很长时间,而我只使用了这一部分:ServerCertificateCustomValidationCallback =(sender,cert,chain,sslPolicyErrors)=> { //bypass return true; } - Karlomanio

10

如果您正在使用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);

3
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();

1
我遇到了类似的问题,但错误信息略有不同:

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的修复方法,将相同的代码放入iOS的FinishedLaunching (AppDelegate.cs)中也应该有效。

0
将以下代码放入 MainActivity.cs 的 OnCreate 方法中: 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(new System.Net.Http.HttpClientHandler());

  • 还有别忘了使用 IP 地址而不是 localhost。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接