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