【问题标题】:How to allow HTTPS connections from both localhost and container towards an ASP.NET Core Web API application?如何允许从本地主机和容器到 ASP.NET Core Web API 应用程序的 HTTPS 连接?
【发布时间】:2020-09-11 19:01:07
【问题描述】:

我正在尝试将 Docker 用于现有应用程序,但遇到以下问题。当 API 尝试从容器中获取 Identity Server 元数据时,它会失败并显示以下内容:

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

主机浏览器确实确认了这一点(Chrome中的验证错误)。

如果我使用 localhost 而不是 host.docker.internal 访问相同的元数据,它会按预期工作。

我已使用来自here 的说明来创建并信任身份服务器也使用它的本地主机证书:

dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\aspnetapp.pfx -p { password here }
dotnet dev-certs https --trust

我假设这些说明仅为 localhost 创建证书,但我正在尝试获得一个也适用于 host.docker.internal 的解决方案。

问题:如何允许从本地主机和容器到 ASP.NET Core Web API 应用程序的 HTTPS 连接?

【问题讨论】:

    标签: docker asp.net-core https ssl-certificate


    【解决方案1】:

    我认为你是对的 - dotnet dev-certs 只为 localhost 生成证书。据我所知,这是不可配置的。因此,您似乎必须生成自己的自签名证书并信任它。假设您使用的是 Windows,一种方法是使用 Powershell's New-SelfSignedCertificate

    #create a SAN cert for both host.docker.internal and localhost
    $cert = New-SelfSignedCertificate -DnsName "host.docker.internal", "localhost" -CertStoreLocation cert:\localmachine\my
    
    #export it for docker container to pick up later
    $password = ConvertTo-SecureString -String "123123" -Force -AsPlainText
    Export-PfxCertificate -Cert $cert -FilePath C:\https\aspnetapp.pfx -Password $password
    
    # trust it on your host machine
    $store = New-Object System.Security.Cryptography.X509Certificates.X509Store "TrustedPublisher","LocalMachine"
    $store.Open("ReadWrite")
    $store.Add($cert)
    $store.Close()
    

    假设您使用 Microsoft 为您的应用提供的基础映像,提示 Kestrel 选择新证书,您可能必须像这样 run docker

    docker pull your_docker_image
    docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="123123" -e ASPNETCORE_Kestrel__Certificates__Default__Path=\https\aspnetapp.pfx -v %USERPROFILE%\.aspnet\https:C:\https\ your_docker_image
    
    docker run <your image> --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="123123" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
    

    请注意,我将证书导出到 C:\https,然后将其安装到容器上。

    您可能不得不尝试使用路径和域名,但希望这可以为您提供一个起点。

    OpenSSL 是另一种可能的跨平台解决方案

    UPD 由于 Docker 机器通常是 Linux,因此这个答案可能不是一个完整的解决方案。在同一主题上查看我的 other answer - 利用 OpenSSL 执行任务并介绍如何在构建时将自签名证书嵌入到 Docker 映像中。

    【讨论】:

    • 我已经尝试过您的 Powershell 脚本,但它仍然仅适用于 localhost。 Chrome 提到证书必须在 Trusted Root Certification Authorities 中,否则不可信。我已将信任更改为$store = New-Object System.Security.Cryptography.X509Certificates.X509Store [System.Security.Cryptography.X509Certificates.StoreName]::Root,"LocalMachine",但我在中间证书颁发机构内获得了证书。我已将其导出并导入到受信任的根证书颁发机构,但 Chrome 仍然不满意。
    • 也直接将 pfx 导入到 Trusted Root Certification Authorities 证书中,但对于 Chrome 来说仍然不够。
    • 该死 - 我必须发出 docker-compose build 才能正常工作。谢谢。
    猜你喜欢
    • 2015-09-23
    • 2018-09-07
    • 2017-05-03
    • 1970-01-01
    • 2022-11-07
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多