我是移动开发新手,我正在尝试让我的. NET Maui应用程序连接到本地ASP.NET核心网站(API)。
我当前被此异常阻止:
第一个月
I have followed this article https://learn.microsoft.com/en-us/xamarin/cross-platform/deploy-test/connect-to-local-web-services#bypass-the-certificate-security-check
运行dotnet dev-certs https --trust
将返回A valid HTTPS certificate is already present.
我的当前代码是:
HttpClientHandler handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
{
if (cert.Issuer.Equals("CN=localhost"))
return true;
return errors == System.Net.Security.SslPolicyErrors.None;
};
var httpclient = new HttpClient(handler);
var test = await httpclient.PostAsync($"https://10.0.2.2:44393/" + uri, new StringContent(serializedItem, Encoding.UTF8, "application/json"));
但问题是,我从来没有进入ServerCertificateCustomValidationCallback。
我也试过
ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
{
return true;
};
但也没找到。
. NET MAUI中有什么变化吗?
5条答案
按热度按时间euoag5mw1#
当我试图让SignalR客户端连接我的本地测试服务器时,我遇到了完全相同的问题,在深入研究源代码后,我发现
HttpClientHandler
actually usesAndroidMessageHandler
as its underlying handler。虽然
AndroidMessageHandler
实现了ServerCertificateCustomValidationCallback
属性,但在发送请求时从不使用其值。此问题在this pull request中得到解决。现在,要在Android上禁用服务器证书验证,您可以实现一个自定义的
TrustProvider
,它将绕过任何证书验证:如果您还想禁用主机名验证,则需要动态继承
AndroidMessageHandler
并覆盖其内部GetSSLHostnameVerifier
方法,以返回一个伪IHostNameVerifier
:在您的
MauiProgram
中调用DangerousAndroidMessageHandlerEmitter.Register
和DangerousTrustProvider
:最后一步,你需要告诉Xamarin使用你动态生成的
DangerousAndroidMessageHandler
,你应该可以通过在你的csproj
文件中设置AndroidHttpClientHandlerType
为处理程序类型的全限定名来实现:或者将Android运行时环境变量
XA_HTTP_CLIENT_HANDLER_TYPE
设置为处理程序的名称:上述解决方案也适用于
ClientWebSocket
和其他使用SslStream
的应用,这意味着您可以使用WebSocket传输连接到测试SignalR服务器(这是我尝试实现的)。请记住,仅在调试版本中执行此操作。
mklgxw1f2#
在Android平台的MainApplication.cs中:
在ASP.NET核心API程序.cs中:
在Maui程序.cs中:
在ASP.NET核心API启动设置.json中:
jgovgodb3#
简介
因为一些"超级聪明"的评论家认为它会-引用-
为了推广产品或服务而污损帖子,或故意破坏帖子
如果nolex的回答被编辑成
我将更新后的代码作为一个单独的答案发布。
问题
正如nolex在他的回答中已经指出的,
HttpClientHandler
actually usesAndroidMessageHandler
作为它的底层处理程序-它 * 确实 * 实现了已知的ServerCertificateCustomValidationCallback
。然而,它的值在发送请求时从未使用过,您可以通过搜索链接的源代码文件中该属性的另一个示例来轻松地验证自己。甚至有一个pull request从今年2月11日开始等待(进一步的)批准和合并来解决这个问题。但是即使在17天前的今天,它仍然没有合并。另外,5个检查现在又失败了。
唯一的解决方案-暂时是
如果您希望(甚至要求)在运行Android Emulator的同一台机器上运行(调试)服务器构建版本,并且需要它们之间的安全连接,那么您只有一种方法:使用您自己的
DangerousTrustManager
覆盖Android的默认TrustManager
。这允许您的应用绕过***任何***证书验证,因此使用前缀Dangerous
。😉我再怎么强调都不为过,所以再一次:不要***************使用本地运行的调试版本以外的代码。不要在测试环境中使用。不要在临时环境中使用。说真的!
不过,这里也有一个好处:这个解决方案允许任何使用
SslStream
的连接尝试,例如ClientWebSocket
,成功。2因此,你本地SignalR服务器的WebSocket
传输也能正常工作!关于以下代码的注解:
1.由于我为整个MAUI项目启用了
Nullable
,您将在string
s等上看到?
后缀。1.我无法忍受代码在任何地方水平滚动,因此过度使用了换行符。
好吧,让我们进入正题:
MyMauiApp\Platforms\Android\DangerousTrustProvider.cs
:由于Android执行额外的主机名验证,因此还需要动态继承
AndroidMessageHandler
,以便通过返回一个伪IHostNameVerifier
来覆盖其内部GetSSLHostnameVerifier
方法。MyMauiApp\Platforms\Android\DangerousAndroidMessageHandlerEmitter.cs
:作为最后一步,需要为Android MAUI调试构建注册新创建的类型。
MyMauiApp\MauiProgram.cs
:最后,为了让MAUI/Xamarin * 真正 * 使用动态生成的
DangerousAndroidMessageHandler
,需要在MyMauiApp.csproj
文件中包含一个AndroidHttpClientHandlerType
属性,该属性包含***两次***处理程序的名称。MyMauiApp\Platforms\Android\MyMauiApp.csproj
:或者,也可以将Android运行时环境变量
XA_HTTP_CLIENT_HANDLER_TYPE
设置为相同的值:结束
在正式修复到来之前,请记住:为了这个世界的安全,不要在生产中使用这个!
现在,去追逐你的(应用)梦想吧🥳
btqmn9zl4#
如果我们被迫实现覆盖证书验证的类,强调这一点,而不离开开发环境,可能也会用更少的代码行做坏事。
把https改成http就行了。
在客户端项目中,将API的URL更改为http,并在AndroidManifest. xml中添加
android:usesCleartextTraffic="true"
。在服务器项目中注解掉行app. UseHttpRedirection();
这太可怕了,我希望它能很快得到修复。
syqv5f0l5#
忽略所有证书的替代方案是install certificate on your dev device yourself,它也将解决MAUI/Xamarin问题与ServerCertificateCustomValidationCallback的Android SSL连接。对于iOS,它的工作开箱即用,对于Android,你需要允许应用使用用户证书,如下所述:如何在Android设备上安装可信CA证书?