You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure AppService调用Azure VM API报UntrustedRoot证书链错误求助

问题描述

我将.NET6/C#客户端Web应用部署在Azure App Service中,用于调用部署于Azure VM、需MSAL认证的API。客户端已完成认证,但调用API失败,报错信息如下:

The SSL connection could not be established, see inner exception. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot at System.Net.Security.SslStream.SendAuthResetSignal(ProtocolToken message, ExceptionDispatchInfo exception) at System.Net.Security.SslStream.CompleteHandshake(SslAuthenticationOptions sslAuthenticationOptions) at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm) at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken) --- End of inner exception stack trace --- at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(HttpRequestMessage request

本地运行客户端Web应用时可正常调用API,仅Azure环境间的调用出现该异常。客户端与API均为企业内部服务,API使用的SSL证书由企业内部签发。我已将API同款PFX证书上传至App Service的证书管理区域,但仍收到相同错误:

The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot

请问除上传PFX证书外,还需执行哪些操作?能否提供相关官方文档指引以解决该错误?是否有人遇到过类似场景?非公共CA签发证书是否为问题根源?

解决方案

问题根源

非公共CA签发的证书确实是问题核心。Azure App Service默认只信任公共CA的根证书,企业内部CA不在默认信任列表里。你上传的是API的PFX证书(包含API的私钥和证书链),但App Service仍无法识别企业内部CA为可信根,所以证书链验证失败,报UntrustedRoot错误。

需执行的额外步骤

1. 导出企业内部CA的根证书(公钥版)

从企业内部CA服务器导出根证书的**DER编码二进制X.509(.CER)**格式文件——只需要公钥,不要用PFX(PFX包含私钥,没必要上传到App Service)。

2. 将根CA证书上传到App Service的公钥证书存储

可以通过Azure门户或Azure CLI操作:

  • 门户操作:
    1. 进入目标App Service,打开TLS/SSL设置。
    2. 切换到公钥证书(.cer)选项卡,点击上传证书。
    3. 选择导出的根CA证书文件,填写友好名称后完成上传。
  • Azure CLI命令:
    az webapp config ssl upload --name <你的App Service名称> --resource-group <资源组名称> --certificate-file <本地根CA证书路径> --certificate-name <证书友好名称>
    

3. 配置App Service加载并信任该根证书

在App Service的应用设置中添加两个配置项:

  1. 进入配置 -> 应用程序设置。
  2. 添加:
    • 键:WEBSITE_LOAD_CERTIFICATES,值:*(表示加载所有上传的证书,也可以填根CA证书的拇指print)
    • 键:WEBSITE_ROOT_CERTIFICATES,值:根CA证书的拇指print(从Azure门户的证书详情页复制)

4. 调整.NET HttpClient的证书验证逻辑(可选但推荐)

为了确保客户端明确信任企业CA,可在代码中自定义HttpClient的证书验证回调:

using System.Security.Cryptography.X509Certificates;
using System.Net.Http;
using System.Net.Security;

var handler = new HttpClientHandler();
// 加载根CA证书(可以嵌入到应用,或者从App Service证书存储读取)
var trustedRootCert = new X509Certificate2("RootCA.cer");

handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, errors) =>
{
    // 如果没有错误直接通过
    if (errors == SslPolicyErrors.None)
        return true;
    
    // 检查证书链中是否包含信任的根CA
    foreach (var chainElement in chain.ChainElements)
    {
        if (chainElement.Certificate.Thumbprint.Equals(trustedRootCert.Thumbprint, StringComparison.OrdinalIgnoreCase))
            return true;
    }
    
    // 其他情况拒绝
    return false;
};

var httpClient = new HttpClient(handler);
// 使用httpClient调用目标API

常见场景说明

很多企业在Azure内部部署服务时都会碰到这个问题,尤其是内部API用私有CA证书的情况。本质就是Azure PaaS服务默认只认公共CA,必须手动把私有CA根证书加入信任体系。

官方文档核心要点

Azure官方文档关于App Service证书信任的关键内容:

  • App Service的公钥证书存储:上传的.cer证书会被存入信任存储,但需要通过WEBSITE_LOAD_CERTIFICATES让应用能够访问。
  • 自定义根证书配置:通过WEBSITE_ROOT_CERTIFICATES指定要信任的根证书拇指print,App Service会在SSL握手时用它来验证证书链。

内容的提问来源于stack exchange,提问作者roney

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 08:05:29