【发布时间】:2018-10-05 07:38:27
【问题描述】:
我正在开发一个 Xamarin.Forms 应用程序,该应用程序需要使用 ASP.NET Core 2.1 API 中公开的一些数据,我正在开发服务和 Xamarin 应用程序,因此一切都在 MAC OS 上本地运行。
我面临的问题是在向 ASP.NET Core API 发送请求时发生的,它似乎与 ASP.NET Core 2.1 中默认启用的 HTTPS 协议有关,当我运行它启用的 api 时默认 URL https://localhost:5001 是我在 Xamarin 应用程序中定位的 URL。
在 Android 中,我可以将请求发送到 API,但是一旦发回响应,xamarin 应用就会引发以下异常:
Error in AppLoginViewModel.Login Javax.Net.Ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. ---> Java.Security.Cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. ---> Java.Security.Cert.CertPathValidatorException: Trust anchor for certification path not found.
--- End of inner exception stack trace ---
--- End of inner exception stack trace ---
at Java.Interop.JniEnvironment+InstanceMethods.CallVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00069] in <fb2a9245146c43afbafe6628542c6726>:0
at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeAbstractVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x00014] in <fb2a9245146c43afbafe6628542c6726>:0
at Javax.Net.Ssl.HttpsURLConnectionInvoker.Connect () [0x0000a] in <9c89490198b4401e89a0f0bf9e68c7be>:0
at Xamarin.Android.Net.AndroidClientHandler+<>c__DisplayClass43_0.<ConnectAsync>b__0 () [0x0005a] in <9c89490198b4401e89a0f0bf9e68c7be>:0
at System.Threading.Tasks.Task.InnerInvoke () [0x0000f] in <5b7c58d953774179ac771c086a8fa093>:0
at System.Threading.Tasks.Task.Execute () [0x00000] in <5b7c58d953774179ac771c086a8fa093>:0
--- End of stack trace from previous location where exception was thrown ---
at Xamarin.Android.Net.AndroidClientHandler+<DoProcessRequest>d__45.MoveNext () [0x0012e] in <9c89490198b4401e89a0f0bf9e68c7be>:0
--- End of stack trace from previous location where exception was thrown ---
at Xamarin.Android.Net.AndroidClientHandler+<SendAsync>d__40.MoveNext () [0x00230] in <9c89490198b4401e89a0f0bf9e68c7be>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Http.HttpClient+<SendAsyncWorker>d__49.MoveNext () [0x000ca] in <006b95df38b04983b2ec7f1bf1c32608>:0
--- End of stack trace from previous location where exception was thrown ---
at AuditoriasCiudadanas.Mobile.Core.Services.RestService+<Seguridad_ValidarEmailAuditorAsync>d__16.MoveNext () [0x00184] in /Users/jorgeramirez/VSProjects/AuditoriasCiudadanas.Mobile/src/AuditoriasCiudadanas.Mobile.Core/Services/RestService.cs:242
--- End of stack trace from previous location where exception was thrown ---
at AuditoriasCiudadanas.Mobile.Core.Services.AuthService+<ValidarEmailAuditor>d__6.MoveNext () [0x0002b] in /Users/jorgeramirez/VSProjects/AuditoriasCiudadanas.Mobile/src/AuditoriasCiudadanas.Mobile.Core/Services/AuthService.cs:28
--- End of stack trace from previous location where exception was thrown ---
at AuditoriasCiudadanas.Mobile.Core.ViewModels.AppForgotPasswordViewModel+<ValidarEmail>d__27.MoveNext () [0x0006f] in /Users/jorgeramirez/VSProjects/AuditoriasCiudadanas.Mobile/src/AuditoriasCiudadanas.Mobile.Core/ViewModels/AppForgotPasswordViewModel.cs:82
--- End of managed Javax.Net.Ssl.SSLHandshakeException stack trace ---
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:229)
at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:192)
at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:149)
at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:112)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:184)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:89)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:26)
Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:661)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:539)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:495)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:418)
at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:339)
at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)
at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)
at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:208)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.verifyCertificateChain(ConscryptFileDescriptorSocket.java:404)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:375)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:224)
... 12 more
Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
... 24 more
在 iOS 中行为是相同的,xamarin 应用在收到响应时会抛出异常
Error in AppLoginViewModel.Login System.Net.WebException: An SSL error has occurred and a secure connection to the server cannot be made. ---> Foundation.NSErrorException: Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=(
"<cert(0x7fce57040e00) s: localhost i: localhost>"
), NSErrorClientCertificateStateKey=0, NSErrorFailingURLKey=https://localhost:5001/api/auth, NSErrorFailingURLStringKey=https://localhost:5001/api/auth NSUnderlyingError=0x600001fccc60 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x6000023ce400>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x7fce57040e00) s: localhost i: localhost>"
)}}, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <31AF1DE2-4C56-4480-9F1D-0E9B7C7B8D9A>.<1>"
), _kCFStreamErrorCodeKey=-9802, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <31AF1DE2-4C56-4480-9F1D-0E9B7C7B8D9A>.<1>, NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x6000023ce400>, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made.}
--- End of inner exception stack trace ---
at System.Net.Http.NSUrlSessionHandler+<SendAsync>d__29.MoveNext () [0x001c3] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/src/Foundation/NSUrlSessionHandler.cs:202
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Http.HttpClient+<SendAsyncWorker>d__48.MoveNext () [0x00080] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/external/mono/mcs/class/System.Net.Http/System.Net.Http/HttpClient.cs:276
--- End of stack trace from previous location where exception was thrown ---
at AuditoriasCiudadanas.Mobile.Core.Services.RestService+<Seguridad_ValidarEmailAuditorAsync>d__16.MoveNext () [0x00184] in /Users/me/RestService.cs:242
--- End of stack trace from previous location where exception was thrown ---
at AuditoriasCiudadanas.Mobile.Core.Services.AuthService+<ValidarEmailAuditor>d__6.MoveNext () [0x0002b] in /Users/me/AuthService.cs:28
--- End of stack trace from previous location where exception was thrown ---
at AuditoriasCiudadanas.Mobile.Core.ViewModels.AppForgotPasswordViewModel+<ValidarEmail>d__27.MoveNext () [0x0006f] in /Users/me/AppForgotPasswordViewModel.cs:82
无法使用 HTTPS 进行本地调试吗?我需要更改哪些内容才能同时调试移动应用和 api?
感谢您的帮助
【问题讨论】:
-
当您创建一个新项目时,它使用自签名证书,该证书不受创建它的机器之外的任何人的信任。要么信任模拟器中的证书,要么暂时在您的代码中暂停证书验证 - 您的代码在哪里?另一种选择是为 Web API 创建一个有效的证书,例如使用 Let's Encrypt
-
@PanagiotisKanavos 一切都是本地的,我刚刚使用 Visual Studio 模板创建了 asp.net 核心项目,AFAIK 默认启用 SSL,所以我没有做任何更改
-
正如我所说,这与 HTTP 无关。该证书是自签名的,因此不受信任。 任何语言或项目的项目模板无法知道您是否购买了证书或使用 Let's Encrypt 创建了证书,因此它必须使用自签名证书。您必须在部署之前使用有效的证书配置项目
-
顺便说一句,你必须添加一个有效的证书 - 我很确定你不想创建任何不使用 SSL 连接的 Android 或 iOS 应用程序对其服务
-
是否可以为本地主机创建有效的证书?
标签: xamarin asp.net-core xamarin.forms asp.net-core-webapi asp.net-core-2.1