MySQLデータベースからデータを取得するためにRESTful APIにアクセスしようとしています。すべてがセットアップされ、C#WPFプロジェクトで完全に機能します。しかし、Xamarinフォーム(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とは異なる動作をしていますか?
Apache設定エラー であることが判明しました。私は ドメインをチェックした でエラーに気づいた。これは、私の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; };
そのコードはunsafeであり、テストにのみ使用する必要があります。
2つの異なるプロジェクトタイプの使用が原因でFlurl.Httpが失敗する可能性があります(.net標準とクラスライブラリ-私が書いたhttpクライアントでまったく同じ問題が発生しました)
.net標準の別のhttpクライアントを試してください。
いずれにせよ、独自のhttpクライアントを作成してデバッグすることができます。これが私の推奨事項です。
それでも立ち往生している場合-返信して私がお手伝いします。