Nouman Bhatti
Nouman Bhatti

Reputation: 1421

How to use development certificate from windows host machine on windows docker container running .net core

it's a dotnet core app and running it inside a windows container. port 80 and 443 (https) are exposed.

I'm using the default Dockerfile generated by VS

#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

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

FROM build AS publish
RUN dotnet publish "IdentityServer.csproj" -c Development -o /app/publish /p:UseAppHost=false

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

I'm following this Hosting ASP.NET Core images with Docker over HTTPS & Developing ASP.NET Core Applications with Docker over HTTPS to build docker images using host windows system development certificate.

Ran these 2 commands as per the articles above. I made sure the certificate name, in this case (IdentityServer.pfx) match the project assembly name.

dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\IdentityServer.pfx -p crypticpassword
dotnet dev-certs https --trust

than using the following command to create an image

docker build -t identity -f IdentityServer/Dockerfile .

after the image is build successfully which I can confirm image is successfully created by running the command

docker images ls

After all this I'm running the command as per the articles

docker run --rm -it -p 8080:80 -p 8081:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8081 -e ASPNETCORE_Kestrel__Certificates__Default__Password="crypticpassword" -e ASPNETCORE_Kestrel__Certificates__Default__Path=$env:USERPROFILE\.aspnet\https\IdentityServer.pfx -v $env:USERPROFILE\.aspnet\https:C:\https\ --user ContainerAdministrator identity

The above command fails with the following error

Unhandled exception. System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Users\Administrator.aspnet\https\IdentityServer.pfx'.

info: Duende.IdentityServer.Startup[0] Using the default authentication scheme Identity.Application for IdentityServer Unhandled exception. System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Users\Administrator.aspnet\https\IdentityServer.pfx'. at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options) at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable1 unixCreateMode) at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable1 unixCreateMode) at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable1 unixCreateMode) at System.IO.StreamReader.ValidateArgsAndOpenPath(String path, Encoding encoding, Int32 bufferSize) at System.IO.File.ReadAllText(String path, Encoding encoding) at System.Security.Cryptography.X509Certificates.X509Certificate2Collection.ImportFromPemFile(String certPemFilePath) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Certificates.CertificateConfigLoader.LoadCertificate(CertificateConfig certInfo, String endpointName) at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadDefaultCert() at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Reload() at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Load() at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.BindAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.StartAsync[TContext](IHttpApplication1 application, CancellationToken cancellationToken) at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken) at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken) at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token) at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token) at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host) at Program.$(String[] args) in C:\src\IdentityServer\Program.cs:line 14

enter image description here

I'm not using User secrets to save the password which is different to the articles.

Any idea What I'm doing wrong here :(

I also referred to this stack overflow existing question but it doesn't help

UPDATE:

Now I've also added the user secrets as below

{
    "Kestrel":{
        "Certificates":{
            "Default":{
                "Path":     "/root/.aspnet/https/<AppName>>.pfx",
                "Password": "<<Your-Password>>"
            }
        }
    }
}

Upvotes: 1

Views: 638

Answers (1)

Nouman Bhatti
Nouman Bhatti

Reputation: 1421

So I managed to make it work with following steps. I don't think all of these steps required other than the change in the docker run command.

1. Remove existing dev certificates

dotnet dev-certs https --clean

2. Create, trust and export your new development certificate

Generate a new self-signed certificate, trust it and also export it to a password-protected .pfx file, all in a single step, otherwise it won't work properly.

In the same PowerShell prompt, run the following command, replacing SECRETPASSWORD with a secret password of your own choosing:

dotnet dev-certs https --trust -ep
$env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p SECRETPASSWORD
  1. Change in the docker run command

for environment variable ASPNETCORE_Kestrel__Certificates__Default__Path. I changed the value form pointing to host system drive to the drive on docker i.e. change value $env:USERPROFILE.aspnet\https\IdentityServer.pfx to c:\https\IdentityServer.pfx . updated command will be

docker run --rm -it -p 8080:80 -p 8081:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8081 -e ASPNETCORE_Kestrel__Certificates__Default__Password="crypticpassword" -e ASPNETCORE_Kestrel__Certificates__Default__Path=c:\https\IdentityServer.pfx -v $env:USERPROFILE\.aspnet\https:C:\https\ --user ContainerAdministrator identity

Upvotes: 1

Related Questions