我正在尝试对具有2个SSL证书的站点进行HTTPS调用:自签名证书和由第一个证书签名的证书。当我使用HttpClient向站点发送请求时,控制台会记录一个不受信任的链,显示两个证书,然后打印由java.security.cert.CertPathValidatorException: Trust anchor for certification path not found
引起的长堆栈跟踪。
我已经在手机上安装了两个证书,导航Chrome到该站点显示了一个可信连接(在我安装证书之前它有一个不受信任的连接警告)。我认为问题在于App拒绝信任自签名证书。我无权访问服务器,因此对其证书没有影响,因此安装由可信CA签名的证书是不可行的。
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);
我能够在Android和iOS上都能使用它。
iOS很简单,只需覆盖ServicePointManager.ServerCertificateValidationCallback
:
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
对于Android,我使用了Bruno Caceiro's answer from a similar question和创建的依赖服务。
在我的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;
}