【问题标题】:Docker image error The remote certificate is invalid according to the validation procedure on client web-applicationDocker 镜像错误 根据客户端 Web 应用程序上的验证程序,远程证书无效
【发布时间】:2021-07-26 06:20:52
【问题描述】:

我的客户端 WebApp(作为单独的 Linux docker 映像端口 4443 运行)上总是出现以下错误:

System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'https://host.docker.internal:8443/.well-known/openid-configuration'.
---> System.IO.IOException: IDX20804: Unable to retrieve document from: 'https://host.docker.internal:8443/.well-known/openid-configuration'.
---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.

它连接到我的 IdentityServer4(作为单独的 Linux docker 映像端口 4444 运行)。 在 IS4 Startup.cs 中,我创建了以下代码的证书:

...
var idpUri = configuration["AppConfig:IdentityProviderUrl"];
var dnsName = new Uri(idpUri).DnsSafeHost;
var cert = new X509Certificate2(Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(),"certificate.pfx")));
var builder = services.AddIdentityServer(options => {
      options.IssuerUri = idpUri;
   }).AddSigningCredential(cert); //A self-signed PFX certificate located in the root of the IS4 and also copied in de client app used for Kestrel cert.
...

在我的客户端 WebApp 中,我插入了以下代码来设置权限:

  string identityProviderUrl = Configuration.GetValue<string>("AppConfig:IdentityProviderUrl");
  services.AddHttpClient(AUTHORIZATION_SERVICE_CLIENT_NAME, client => {
     client.BaseAddress = new Uri(identityProviderUrl);
     client.DefaultRequestHeaders.Clear();
     client.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
  });
  services.AddAuthentication("Bearer") 
     .AddJwtBearer("Bearer", options => { //NOTE: I don't know if this is needed
            options.Authority = identityProviderUrl;
            options.TokenValidationParameters = new TokenValidationParameters {
            ValidateAudience = false
         };
      });
   services.AddAuthentication(options => {
      options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
      options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
   }).AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options => {
         options.Authority = identityProviderUrl;
         options.ClientId = oidcClientId;
         options.ClientSecret = oidcClientSecret;
         ...
      });

我认为我正在创建的证书有问题,这两个 docker 映像上都没有。但是 Docker 容器都使用 HTTPS 运行,否则根本不会启动。我在这里错过了什么?

让我们按照下面评论中的建议由 LetsEncrypt 来做吧。 我下载并运行这个项目 (src:https://github.com/PKISharp/ACMESharpCore/tree/master/src/examples/ACMECLI) 设置以下属性:

public string CaName { get; } = Constants.LetsEncryptStagingName;
public IEnumerable<string> Email { get; } = new string[] { "xxx@gmail.com" };
public bool AcceptTos { get; } = true;
public IEnumerable<string> Dns { get; } = new string[] { "xxx.duckdns.org" };
public (bool enabled, int? timeout) WaitForAuthz { get; } = (true, 300);
public bool Finalize { get; } = true;
public string ExportPfx { get; } = @"c:\tmp\certificate.pfx";
public string ExportPfxPassword { get; } = " ";

但它仍然悬而未决,已经有几天了。我不知道它什么时候有效。

【问题讨论】:

    标签: docker asp.net-core ssl identityserver4 x509certificate2


    【解决方案1】:

    您不能拥有用于 HTTPS 的自签名证书,而是获得真正的证书,或者您必须将证书添加到客户端受信任的证书存储中。

    问题是客户端在尝试建立安全通道时不信任它收到的证书。

    在内部正确使用 HTTPS 是容器之间的最佳实践。

    要在 ASP.NET Core 中支持 HTTPS,请参阅这篇文章:

    今天我也很高兴获得您的证书表格LetsEncrypt。使用它们可以让您自动创建证书。

    【讨论】:

    • 感谢您的回答。我喜欢最佳实践。你建议我改变什么来让它工作?您在内部和正确地使用 HTTPS 是什么意思,您的意思是 Kestrel 用来支持 HTTPS 的证书?能举个例子吗?
    • 感谢您的更新。我读了这篇文章 Enforce HTTPS。我已经完成了 app.UseHttpsRedirection 部分。当我输入 HTTP url 时,我认为它会重定向到 HTTPS。但是我看不到这如何解决我的证书问题并使用此 .AddSigningCredential(cert) 部分。或者我可以摆脱这个吗?我已经查看了 LetsEncrypt,但是如何正确实现它。我在这里有一个例子:github.com/Carlos-Carreno-Berlanga/TestLetsEncrypt/tree/master/…。但是运行时似乎有错误。我在帖子中附上了错误。你能帮帮我吗?
    • 当我使用 github.com/PKISharp/ACMESharpCore 库生成证书时,/src/examples/ACMECLI 中的 CLI 示例对我来说效果很好。在其他项目中我使用过naturalborncoder.com/linux/2021/01/27/…
    • 另外,AddSigningCredential 不是关于 HTTPS,而是关于如何签署 JWT 令牌
    • 感谢您的更新。所以当我正确理解你时。 1) 出现此错误消息是因为证书无效并且不受在我的本地 docker 主机上运行 Kestrel 的 2 docker 容器的信任,并且需要有效的证书来与 2 个 webapps 之间的令牌通信?并且是由 Kestrel 无效证书引起的吗? 2) 你每 90 天通过运行这个 CLI 项目更新 LetsEncrypt 证书并将其推送到你的项目。我理解你的正确吗? 3)这个错误与这个.AddSigningCredential()无关吗?
    猜你喜欢
    • 2019-01-30
    • 2016-12-12
    • 1970-01-01
    • 2011-03-28
    • 2016-11-28
    • 2023-01-18
    • 2013-08-08
    相关资源
    最近更新 更多