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

Posted

技术标签:

【中文标题】忽略 Xamarin.Forms (PCL) 中的 SSL 证书错误【英文标题】:Ignore SSL certificate errors in Xamarin.Forms (PCL) 【发布时间】:2015-04-22 04:35:52 【问题描述】:

有没有办法做类似这里描述的事情:https://***.com/a/2675183 但在 Xamarin.Forms PCL 应用程序中?我正在使用 HttpClient 连接到服务器。

【问题讨论】:

【参考方案1】:

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

【讨论】:

这对我不起作用。回调永远不会被调用,并且会生成一个表明 SSL 无效的异常 AndroidClientHandler 似乎不支持 ServerCertificateValidationCallback。你有任何更新的信息来处理 Android 上的这个问题吗? 此解决方案不适用于 Android【参考方案2】:

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

【讨论】:

在此处的所有解决方案中,这一解决方案在 2019/20 最新更新后适用于 VS2019 for Android。 应用上述代码后仍然出现同样的错误。【参考方案3】:

如果您使用AndroidClientHandler,则需要提供SSLSocketFactoryHostnameVerifier 的自定义实现,并禁用所有检查。为此,您需要继承 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);

【讨论】:

【参考方案4】:

我遇到了这个问题,但错误消息略有不同:

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) 也应该可以工作。

【讨论】:

【参考方案5】:
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();

【讨论】:

【参考方案6】: 把这行代码放在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地址而不是使用本地主机

【讨论】:

以上是关于忽略 Xamarin.Forms (PCL) 中的 SSL 证书错误的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法使用 Xamarin.Forms PCL 项目中的 Devexpress.Xamarin.Android.Charts

如何从 Xamarin.forms pcl 中的 Url 检索 json 字符串

如何从 Xamarin.forms pcl 中的 Url 检索 json 字符串

Xamarin.Forms 中的 MVVMLight 的 EventToCommand

Xamarin.Forms PCL/SAP 自定义渲染,支持paintcode 3

为啥我不能在 Xamarin Forms 中选择 PCL 项目?