DEV Community

Christos Matskas for The 425 Show

Posted on

.NET 7 WebApp with Https in Docker, secured by Azure AD

I have to admit, this was a weird and tough one. All I wanted to do was run an ASP.NET Razor Pages app inside a container using Https and Azure Active Directory authentication. Well, this was definitely a fun one to solve. In this blog post I'll show you exactly how to do the following:

  • export the .NET Dev certs to use with Docker
  • configure the Azure AD authentication
  • configure the SameSite cookie policy in .NET
  • configure Docker to use the dev-certs

Export the .NET Dev certs

In order to be able to work in local dev with Docker and HTTPS we need a certificate. And the easiest way to get a cert is to use the .NET dev certs - they are free and available.

Note: this should only be used for local Dev to unblock certain scenarios

Open your favorite terminal and type the following

dotnet dev-certs https --clean
dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\aspnetapp.pfx -p <your secret>

### If you're using PowerShell, then you have to use the following command instead
dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p <your secret>

dotnet dev-certs https --trust
Enter fullscreen mode Exit fullscreen mode

Configure the ASP.NET Core Web App

By default, ASP.NET Core website have HSTS and HTTPS redirection enabled. This means that when running the application, it will expect and redirect all requests to the TLS-enabled port. I like to set mine to the standard 5001 since .NET 6 and 7 are now randomizing the app ports. You can change the default ports in the Properties\launchSettings.json file. This is what mine looks like:

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:43362",
      "sslPort": 44382
    }
  },
  "profiles": {
    "AzureADAuthInDocker": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "http://localhost:5000;https://localhost:5001",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

Implement the necessary authentication, you need to add the following NuGet packages:

  • Microsoft.Identity.Web
  • Microsoft.Identity.Web.UI

In the appsettings.json file add the following AzureAD specific settings:

"AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "<your Azure AD tenant name>.onmicrosoft.com",
    "TenantId": "<your Azure AD tenant ID>",
    "ClientId": "<your Azure AD App Registration client ID>",
    "CallbackPath": "/signin-oidc"
  },
Enter fullscreen mode Exit fullscreen mode

Update the program.cs add the following code:

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));

builder.Services.AddAuthorization(options =>
{
    // By default, all incoming requests will be authorized according to the default policy.
    options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddRazorPages()
    .AddMicrosoftIdentityUI();


// code ommitted

app.UseAuthentication();
app.UseAuthorization();

Enter fullscreen mode Exit fullscreen mode

At this point you can run the application locally using dotnet run and if everything has been configured correctly, you should be prompted to authenticate with your organizational (Azure AD) account

Create a Cookie Policy

If you plan on using Cookies in your solution, then you need to add a cookie policy. In Program.cs above the authentication settings, add the following code:

builder.Services.Configure<CookiePolicyOptions>(
    options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
        options.Secure = CookieSecurePolicy.Always;
    });
Enter fullscreen mode Exit fullscreen mode

Then, just above the app.UseAuthentication() you need to add this:

app.UseCookiePolicy();
Enter fullscreen mode Exit fullscreen mode

Run the application and test that everything's working as expected!

If you get a cookie error as per below, make sure you have the right settings. Check everything and try again:

Image description

Configure Docker for our web app

There are some prerequisites when it comes to working with Docker, namely that you need to have Docker Desktop installed and WSL2 enabled if you want to use Linux containers. Make sure to have these installed correctly.

When it comes to creating the Docker files, I like to lean on VS Code to do the heavy lifting for me. You can find the information on how to set things up for your ASP.NET app here

Running the appropriate Docker commands from the VS Code pallette, should generate the following 3 files:

  • Dockerfile
  • docker-compose.yml
  • docker-compose.debug.yml

I left my Dockerfile mostly unchanged apart from the ENV ASPNETCORE_URLs value which I updated to: http://+:5000;https://+:5001

My docker-compose.yml file looks like this:

version: '3.4'

services:
  azureadauthindocker:
    image: azureadauthindocker
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - 5000:5000
Enter fullscreen mode Exit fullscreen mode

And finally, the bulk of the changes took place in the docker-compose.debug.yml

# Please refer https://aka.ms/HTTPSinContainer on how to setup an https developer certificate for your ASP .NET Core service.

version: '3.4'

services:
  azureadauthindocker:
    image: azureadauthindocker
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - 5000:5000
      - 5001:5001
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:5001;http://+:5000
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
      - ASPNETCORE_Kestrel__Certificates__Default__Password=<your secret>
    volumes:
      - ~/.vsdbg:/remote_debugger:rw
      - C:\Users\chmatsk\.aspnet\https:/https/:ro
Enter fullscreen mode Exit fullscreen mode

With these changes, I can run my web app inside Docker directly from VS Code.

And this is an example with everything working end-to-end

Image description

If you want to run the container from the command line, then this is the command you need to use

docker run --rm -it -p 5000:5000 -p 5001:5001 -e ASPNETCORE_URLS="https://+:5001;http://+:5000" -e ASPNETCORE_HTTPS_PORT=5001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="<your secret>" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx -v C:\Users\chmatsk\.aspnet\https:/https/ <your image>
Enter fullscreen mode Exit fullscreen mode

Running this command should produce the following output and your website should be accessible on https://localhost:5001

Image description

Reach out if you have any questions!

Discussion (1)

Collapse
antonxsrp profile image
antonxsrp

Is this utilizing a Linux or Windows container?