我正在尝试访问我的RESTful API以从MySQL数据库检索数据。在我的C#WPF项目中,一切都已设置并完美运行。但是,在Xamarin Forms(专为Android构建)中使用完全相同的代码时,我无法与服务器成功进行SSL握手。
我正在使用Flurl.Http(使用HttpClient)建立连接,但是在jsonReader.Wait()上出现异常:
var jsonReader = "https://example.com/my_api/api.php/records/my_table?order=id,desc&size=10"
.WithHeader("Accept", "application/json")
.WithBasicAuth("username", "password")
.GetJsonAsync<JsonRootObject>();
// Wait for completion.
jsonReader.Wait();
这是我的AggregateException:
System.AggregateException: One or more errors occurred. (Call failed. An error occurred while sending the request
GET https://example.com/my_api/api.php/records/my_table?order=id,desc&size=10) ---> Flurl.Http.FlurlHttpException: Call failed. An error occurred while sending the request
GET https://example.com/my_api/api.php/records/my_table?order=id,desc&size=10 ---> System.Net.Http.HttpRequestException: An error occurred while sending the request
---> System.Net.WebException: Error: TrustFailure (Authentication failed, see inner exception.) ---> System.Security.Authentication.AuthenticationException:
Authentication failed, see inner exception. ---> Mono.Btls.MonoBtlsException: Ssl error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED
at /Users/builder/jenkins/workspace/xamarin-android-d16-1/xamarin-android/external/mono/external/boringssl/ssl/handshake_client.c:1132
at Mono.Btls.MonoBtlsContext.ProcessHandshake () [0x00038] in <74989b9daab94528ac2c4b7da235b9c5>:0
at Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake (Mono.Net.Security.AsyncOperationStatus status, System.Boolean renegotiate) [0x000a1] in <74989b9daab94528ac2c4b7da235b9c5>:0
at (wrapper remoting-invoke-with-check) Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake(Mono.Net.Security.AsyncOperationStatus,bool)
at Mono.Net.Security.AsyncHandshakeRequest.Run (Mono.Net.Security.AsyncOperationStatus status) [0x00006] in <74989b9daab94528ac2c4b7da235b9c5>:0
at Mono.Net.Security.AsyncProtocolRequest.ProcessOperation (System.Threading.CancellationToken cancellationToken) [0x000ff] in <74989b9daab94528ac2c4b7da235b9c5>:0
at Mono.Net.Security.AsyncProtocolRequest.StartOperation (System.Threading.CancellationToken cancellationToken) [0x0008b] in <74989b9daab94528ac2c4b7da235b9c5>:0
为什么我的SSL握手失败? Xamarin与WPF有何不同之处?
答案 0 :(得分:0)
由于使用了两种不同的项目类型(.net标准与类库-我编写的http客户端存在完全相同的问题),因此Flurl.Http可能会失败
尝试使用其他.net标准的http客户端。
无论如何,您可以编写自己的http客户端并进行调试-这是我的建议。
如果您仍然卡住,请回信给我。
答案 1 :(得分:0)
原来是Apache configuration error。我checked my domain并发现一个错误。通过在我的Apache指令中添加证书的链文件来解决此问题:
SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
最后一行是缺少的那一行。奇怪的是,即使没有链文件,浏览器和WPF也会信任证书。无论如何,现在它也可以在Android上使用。
同时,我一直在使用这段代码来禁用我的应用程序中的SSL验证:
// This disables the SSL certificate validity check.
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
该代码不安全,仅应用于测试。