You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

.NET MAUI Android应用调用IIS本地HTTPS接口时SSLPeerUnverifiedException(主机名未验证)问题的解决方法

.NET MAUI Android应用调用IIS本地HTTPS接口时SSLPeerUnverifiedException(主机名未验证)问题的解决方法

嘿,我看了你遇到的这个SSL主机名验证问题,咱们一步步来排查解决。你已经做了不少基础配置,但可能在几个细节上还有遗漏,导致Android端还是不认这个证书的主机名。

一、先确认IIS的SSL证书和绑定是否真的正确生效

你用PowerShell生成证书的时候指定了DnsName = "localhost", "192.168.100.2",这一步是对的,但咱们要确认证书的SAN(主题备用名称)里确实包含了这个IP地址:

  • 打开mmc,添加证书管理单元(本地计算机-个人)
  • 找到你生成的那个证书,右键-属性-详细信息,找主题备用名称,确认里面有IP Address=192.168.100.2DNS Name=localhost
  • 另外,检查IIS的绑定:打开IIS管理器,找到默认网站的HTTPS绑定,确认IP地址是192.168.100.2,端口443,证书选的是你生成的那个。

另外,你用PowerShell做的绑定里,New-WebBinding-HostHeader "localhost"可能有问题——当你绑定IP地址的时候,HostHeader应该留空,否则IIS会把这个绑定和localhost的域名绑定关联,而不是IP。你可以修改这个PowerShell命令:

New-WebBinding -Name "Default Web Site" -IPAddress "192.168.100.2" -Port 443 -Protocol "https" -SslFlags 1

去掉-HostHeader "localhost",因为IP绑定不需要主机头,这样IIS才能正确响应来自192.168.100.2:443的请求。

二、修正Android网络安全配置的细节

你的network_security_config.xml框架是对的,但有几个细节要调整:

<?xml version="1.0" encoding="utf-8" ?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="true">localhost</domain>
        <domain includeSubdomains="false">192.168.100.2</domain> <!-- IP地址没有子域名,设为false更准确 -->
        <trust-anchors>
            <certificates src="@raw/iis_ssl_server_certificate"/>
        </trust-anchors>
    </domain-config>
</network-security-config>
  • 把IP地址对应的includeSubdomains改成false,IP不存在子域名,这个设置能避免不必要的匹配逻辑干扰
  • 确认raw目录下的PEM文件命名完全和配置里的一致,且Build Action已经设为AndroidResource

三、MAUI Android代码层面的优化(可选但推荐)

你现在用的是原生HttpsURLConnection,Android端对这种原生API的主机名验证逻辑比较严格,换成MAUI封装的HttpClient会更省心,它会自动适配你配置的网络安全规则:

using System.Net.Http;
using System.Text;

var httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromSeconds(10);
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("SmsGateway/1.0");
httpClient.DefaultRequestHeaders.Accept.ParseAdd("*/*");

var content = new StringContent(strRequestBody, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync("https://192.168.100.2:443/medservices/ReceiveWebhooks.php", content);
isSent = response.IsSuccessStatusCode;

代码更简洁,也能减少原生API带来的适配问题。

如果一定要保留HttpsURLConnection,可以临时加一个自定义主机名验证器(注意:生产环境不建议这么做,仅调试用):

if(connection != null) {
    // 其他配置代码...
    // 添加自定义主机名验证逻辑
    connection.HostnameVerifier = (hostname, session) => 
        hostname.Equals("192.168.100.2") || hostname.Equals("localhost");
    // 后续输出流、响应处理代码...
}

这个验证器会检查请求的主机名是否是你指定的IP或localhost,符合就通过验证。

四、端到端测试确认

  1. 先在电脑上用浏览器打开https://192.168.100.2/medservices/ReceiveWebhooks.php,确认证书显示为信任状态
  2. curl测试:curl -v https://192.168.100.2/medservices/ReceiveWebhooks.php,看是否能正常连接,无SSL错误
  3. 最后运行MAUI Android应用测试POST请求

如果还是有问题,你可以在Android Studio的Logcat里搜索X509TrustManagerSSLPeerUnverified相关的日志,能帮你精准定位是证书不信任还是主机名验证失败。

按照这些步骤调整后,应该就能解决这个SSL主机名验证的问题了,有什么细节问题随时说~

火山引擎 最新活动