C# .Net Core Docker WebApi RemoteCertificateChainError-连接2个Docker容器(UI+;API)

C# .Net Core Docker WebApi RemoteCertificateChainError-连接2个Docker容器(UI+;API),c#,docker,asp.net-core,C#,Docker,Asp.net Core,我有两个.NET核心项目,它们在正常运行时可以完美地协同工作,我有一个API和一个MVC UI。当我在docker容器中运行它们时,我用swagger继续我的API,我想出了如何连接我的PostgreSQL并成功插入数据。当我进入UI并调用API时,我会出现以下错误: 处理请求时发生未处理的异常 AuthenticationException:根据验证过程,远程证书无效:RemoteCertificateNameMismatch,RemoteCertificateChainErrors。 我创建

我有两个.NET核心项目,它们在正常运行时可以完美地协同工作,我有一个API和一个MVC UI。当我在docker容器中运行它们时,我用swagger继续我的API,我想出了如何连接我的PostgreSQL并成功插入数据。当我进入UI并调用API时,我会出现以下错误: 处理请求时发生未处理的异常 AuthenticationException:根据验证过程,远程证书无效:RemoteCertificateNameMismatch,RemoteCertificateChainErrors。 我创建了一个证书并将其保存在.NET项目中。我猜我必须做一些不同的事情才能使这个容器工作。(如果这是错的,我还不确定。) 为了把它放在我的正常项目中,我做了这个

.UseKestrel(serverOptions =>
                {
                    serverOptions.Listen(IPAddress.Loopback, 5010);
                    serverOptions.Listen(IPAddress.Loopback, 5011, listenOptions =>
                    {
                        listenOptions.UseHttps("localpfx.pfx", "password");
                    });
                });
我的.NET核心项目中有一个Dockerfile。我没有使用docker compose。 如何让我的UI调用在不同容器中运行的API?这是我项目的最后一部分。 多谢各位

附言

编辑: Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
#USER ContainerAdministrator
#RUN net localgroup administrators /add "User Manager\ContainerUser"
#USER ContainerUser
WORKDIR /app
EXPOSE 5011
#EXPOSE 5010
EXPOSE 80
ENV ASPNETCORE_ENVIRONMENT=Development
#ENV ASPNETCORE_URLS=https://*:5011

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["UserUISolution.csproj", ""]
RUN dotnet restore "./UserUISolution.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "UserUISolution.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "UserUISolution.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "UserUISolution.dll"]

显然,发生此错误是因为您使用的是自签名证书,并且它不受信任。您需要使
UI
容器信任用于
API
的证书。您可以创建容器,也可以通过编程信任它。对于第二个选项,需要将
HttpClient
配置为信任特定证书

对于
ASP.NET核心
,最好使用它。用户界面项目中的配置如下所示

//this validator will trust incoming certificate with matching thumbprint
public class SingleCertificateValidator
{
    private readonly X509Certificate2 _trustedCertificate;

    public SingleCertificateValidator(X509Certificate2 trustedCertificate)
    {
        _trustedCertificate = trustedCertificate;
    }

    public bool Validate(HttpRequestMessage httpRequestMessage, X509Certificate2 x509Certificate2, X509Chain x509Chain, SslPolicyErrors sslPolicyErrors)
    {
        if (sslPolicyErrors == SslPolicyErrors.None)
            return true;

        string thumbprint = x509Certificate2.GetCertHashString();
        //todo: add more validation logic if needed
        return thumbprint == _trustedCertificate.Thumbprint;
    }
}
Startup.cs中

services
    .AddHttpClient("Default")
    .ConfigurePrimaryHttpMessageHandler(() =>
    {
        var certificate = new X509Certificate2("localpfx.pfx", "password");
        var certificateValidator = new SingleCertificateValidator(certificate);

        return new HttpClientHandler
        {
            ServerCertificateCustomValidationCallback = certificateValidator.Validate
        };
    });
用法


请分享您的dockerfile’您是否使用自签名证书?如果是这样,您是否在您的计算机上信任它?我认为在这种情况下,它可以在您的计算机上正常工作,但不能在容器上工作,因为容器默认不信任证书是的,我创建了一个自签名证书,它也受信任。浏览器中的锁定图标表示对证书有效。当我在kestrel中运行项目时,一切都很好。当我在容器上运行时,它们都是单独工作的,但是当UI调用API时,我得到了错误。另外,我可以在API上使用Swagger。所以昨晚我去掉了容器上的所有HTTPS。我的容器比我的工作得更好!我的UI与我的API对话没有问题。所以现在我100%确定这是一个HTTPS证书问题。我假设我需要在Docker容器中获取证书,然后它就可以工作了。如何从UI调用API?直接通过js或UI使用
HttpClient
从控制器调用API?
services
    .AddHttpClient("Default")
    .ConfigurePrimaryHttpMessageHandler(() =>
    {
        var certificate = new X509Certificate2("localpfx.pfx", "password");
        var certificateValidator = new SingleCertificateValidator(certificate);

        return new HttpClientHandler
        {
            ServerCertificateCustomValidationCallback = certificateValidator.Validate
        };
    });
public class TestController : Controller
{
    private readonly IHttpClientFactory _httpClientFactory;

    public TestController(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    [HttpGet]
    public async Task<IActionResult> TestHttpClient()
    {
        var client = _httpClientFactory.CreateClient("Default");
        var response = await client.GetAsync("url");

        //...
        return Json(result);
    }
}
//...
var certificateValidator = new SingleCertificateValidator(certificate);
var clientHandler = new HttpClientHandler
{
    ServerCertificateCustomValidationCallback = certificateValidator.Validate
};
var client = new HttpClient(clientHandler);
//...