I am trying to use Docker for an existing application and I have the following issue. When the API is trying to get the Identity Server metadata from the container, it fails with the following:
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.
This is indeed confirmed by the host browser (certification error in Chrome).
If I access the same metadata using localhost instead of host.docker.internal, it works as expected.
I have used the instructions from here in order to create and trust a localhost certificate that it is also used by the identity server:
dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\aspnetapp.pfx -p { password here }
dotnet dev-certs https --trust
I assume these instructions create the certificate only for localhost, but I am trying to get a solution that also works for host.docker.internal.
Question: How to allow HTTPS connections from both localhost and container towards an ASP.NET Core Web API application?
I think you are right - dotnet dev-certs
only generates certs for localhost
. And as far as I can tell is not configurable. So it seems you will have to generate your own self-signed cert and trust it. Assuming you're on Windows, one way to do it is with 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()
Assuming you use Microsoft-supplied base images for your apps, to hint Kestrel to pick the new cert up you will probably have to run docker like so:
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
Note I'm exporting the cert to C:\https
which then gets mounted onto the container.
You might have to play around with paths and domain names but hopefully that gives you a starting point.
OpenSSL is another possible solution here that would be cross-platform as well
UPD Since Docker machines are often Linux, this answer might not be a complete solution. Check out my other answer on the same topic - that one leverages off OpenSSL to perform the task and goes into how to embed self-signed certs into Docker images on build.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With