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

Docker环境UI与API通信遇RemoteCertificateNameMismatch证书错误求助

解决Docker环境下UI与API通信的SSL证书验证错误

你遇到的RemoteCertificateNameMismatch和RemoteCertificateChainErrors错误,分别是证书域名不匹配和自签名证书未被信任导致的,以下是针对性的解决方案:

一、修正证书域名匹配问题

API证书的CN(通用名称)是api.example.com,但UI调用API时用的是host.docker.internal:9000,域名不一致触发名称验证失败。需要生成包含host.docker.internal的证书,同时添加SAN(主题备用名称)(现代HTTPS验证要求必须包含SAN)。

修改证书生成Dockerfile(Dockerfile.cert_generator)

FROM alpine:latest

RUN apk --no-cache add openssl

# Create certificates directory
RUN mkdir /certificates

# Generate API certificate with SAN matching host.docker.internal
RUN openssl req -newkey rsa:2048 -nodes -keyout /certificates/api.key -x509 -days 365 -out /certificates/api.crt -subj "/C=GB/ST=London/L=London/O=Dummy Corp/OU=Engineering/CN=host.docker.internal" \
  -addext "subjectAltName=DNS:host.docker.internal,DNS:api.example.com" \
  && openssl pkcs12 -export -out /certificates/api.pfx -inkey /certificates/api.key -in /certificates/api.crt -password pass: \
  && if [ -f "/certificates/api.pfx" ]; then echo "API Certificate Generated Successfully"; else echo "Failed to generate API Certificate"; fi

# Generate UI certificate (可选添加host.docker.internal到SAN)
RUN openssl req -newkey rsa:2048 -nodes -keyout /certificates/ui.key -x509 -days 365 -out /certificates/ui.crt -subj "/C=GB/ST=London/L=London/O=Dummy Corp/OU=Engineering/CN=ui.example.com" \
  -addext "subjectAltName=DNS:ui.example.com,DNS:host.docker.internal" \
  && openssl pkcs12 -export -out /certificates/ui.pfx -inkey /certificates/ui.key -in /certificates/ui.crt -password pass: \
  && if [ -f "/certificates/ui.pfx" ]; then echo "UI Certificate Generated Successfully"; else echo "Failed to generate UI Certificate"; fi

注:删除原Dockerfile中复制到/host_certificates的步骤,因为通过volume挂载./certificates:/certificates已经将证书同步到主机目录。

二、挂载证书到API和UI容器

修改Docker Compose配置,将生成的证书挂载到容器内,并修正Kestrel的证书路径:

version: '3.4'

services:
  integrationtestingbase:
    image: ${DOCKER_REGISTRY-}api
    build:
      context: .
      dockerfile: api/Dockerfile
    ports:
      - "9000:443"
      - "9001:80"
    volumes:
      - ./certificates:/app/certificates  # 挂载证书目录
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
      - Kestrel__Certificates__Default__Path=/app/certificates/api.pfx  # 修正证书路径
      - Kestrel__Certificates__Default__Password=

  integrationtestingwebappbase:
    image: ${DOCKER_REGISTRY-}ui
    build:
      context: .   
      dockerfile: ui/Dockerfile
    ports:
      - "9002:443"
      - "9003:80"
    volumes:
      - ./certificates:/app/certificates  # 挂载证书目录
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
      - Kestrel__Certificates__Default__Path=/app/certificates/ui.pfx  # 修正证书路径
      - Kestrel__Certificates__Default__Password=

  sqlserver:
    image: mcr.microsoft.com/mssql/server:latest
    environment:
      MSSQL_SA_PASSWORD: "Password123!"
      ACCEPT_EULA: "Y"
    ports:
      - "1433:1433"
    volumes:
      - ./path/to/appsettings.json:/app/appsettings.json

  certificate_generation:
    build:
      context: .
      dockerfile: Dockerfile.cert_generator
    volumes:
      - ./certificates:/certificates

三、配置UI的HttpClient信任自签名证书

原代码中重新实例化HttpClient会覆盖依赖注入的配置,且未处理证书信任问题。修改Razor页面代码,通过IHttpClientFactory配置信任自定义证书:

1. 在UI项目的Program.cs中配置HttpClient

var builder = WebApplication.CreateBuilder(args);

// 添加HttpClient并配置证书验证
builder.Services.AddHttpClient("ApiClient", client =>
{
    client.BaseAddress = new Uri("https://host.docker.internal:9000/");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
    var handler = new HttpClientHandler();
    // 加载API的自签名证书
    var certPath = Path.Combine(builder.Environment.ContentRootPath, "certificates", "api.crt");
    var trustedCert = new X509Certificate2(certPath);

    // 自定义证书验证逻辑
    handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
    {
        // 验证证书是否为我们生成的可信证书
        if (cert.Thumbprint == trustedCert.Thumbprint)
            return true;
        // 开发环境下可临时允许所有证书(生产环境禁用)
        // return sslPolicyErrors == SslPolicyErrors.None;
        return false;
    };
    return handler;
});

// 其他配置...
builder.Services.AddRazorPages();

var app = builder.Build();

// 中间件配置...
app.Run();

2. 修改Razor页面的IndexModel

namespace IntegrationTestingWebAppBase.Pages
{
    public class IndexModel : PageModel
    {
        public List<Tenant> Tenants { get; private set; }

        private readonly HttpClient _httpClient;
        private readonly ILogger<IndexModel> _logger;

        // 注入IHttpClientFactory而非直接注入HttpClient
        public IndexModel(ILogger<IndexModel> logger, IHttpClientFactory httpClientFactory)
        {
            _logger = logger;
            _httpClient = httpClientFactory.CreateClient("ApiClient");
        }

        public async Task OnGetAsync()
        {
            try
            {
                var response = await _httpClient.GetAsync("/api/tenant/getall");

                if (response.IsSuccessStatusCode)
                {
                    Tenants = await response.Content.ReadFromJsonAsync<List<Tenant>>();
                }
                else
                {
                    // 处理请求失败逻辑
                }
            }
            catch (HttpRequestException ex)
            {
                if (ex.InnerException is System.Security.Authentication.AuthenticationException authEx)
                {
                    _logger.LogError("SSL/TLS验证错误: {Message}", authEx.Message);
                }
                else
                {
                    _logger.LogError("HTTP请求错误: {Message}", ex.Message);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("未知错误: {Message}", ex.Message);
            }
        }
    }
}

四、运行步骤

  1. 先生成证书:docker-compose up --build certificate_generation
  2. 启动所有服务:docker-compose up --build

这样就能解决证书名称不匹配和证书链信任问题,实现UI与API的正常HTTPS通信。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 10:05:57