ASP.NET core and integrated windows authentication in nanoserver container



Below is overview of steps required to use integrated Windows Authentication in ASP.NET core application inside nanoserver container.

Completion of this instructions will allow you to run nanoserver container in windows AD environment and authenticate users based on their Windows desktop credentials or externally by providing Windows username/password to AD environment. This setup also RBAC access using Windows Groups as explained below.

Entire project with source code located on following github repo (

High level overview of steps required to complete this scenario

  1. Complete first 7 steps in following article (Enabling integrated Windows Authentication in windows docker container)
  2. Build docker container based off github repo above
  3. Launch docker container in AD environment with GMSA account (step 8 in Enabling integrated Windows Authentication in windows docker container)

Detailed instructions


Completion steps 1-7 from following article Enabling integrated Windows Authentication in windows docker container will prepare your AD environment to host windows container with integrated windows authentication.

Add following snippet to startup.cs of your .NET core project which will enabled integrated windows authentication to be used in .NET core

Add .UseIISIntegration() to your  BuildWebHost method of Program.cs

HomeController has 4 methods below. Windows requires authentication and allows only members Domain Admins, Users allow only Domain Users group, LocalUsers allow any account passed by Windows authentication and Anonymousis allowing to be accessed without authentication

So accessing URL on your running container at http://container/home/windows will require authentication and http://container/home/anonymous is allowed to be accessed without authentication.

Multistage build is used to build .NET core project and put in resulting container along with all neccessary prerequisites (IIS and ASP.NET core). For detailed instructions you can read in this article (Using multistage docker build to create IIS + ASP.NET Core image + nanoserver).

Dockerfile for entire project is below. It shall be pretty self explanatory.

Building final image puts together container image consisting of 3 intermediate images used to:

  • Build ASP.NET core project
  • Copy ASP.NET executables to final image
  • Install ASP.NET IIS module to servercore image and copy it over to final image

Once image is built you can deploy to production container host which was prepared earlier in step 1 above.

Launch docker image with following parameters

docker run -d -h containerhost --security-opt "credentialspec=file://win.json" -p 88:80 artisticcheese/winauth:nano-iis

Parameters specify which GMSA account is being used to authenticate to AD and location of JSON file with details.

Accessing URL http://containerhost:88/Home/Windows on container host from domain joined client will automatically log you with current user credentials with no prompt like below. While accessing http://containerhost:88/Home/Anonymous will allow you to access it without username/password.

Accessing with user account which is not part of Domain Admins will return HTTP 403 on /home/windows as expected but will succeed on /home/users

See screenshots below. If you don’t want to automatically log in with default credentials you can access page via IP address which will prevent IE/Chrome from using them., please note that your authentication switches to NTLM instead of Kerberos authentication in such case.

To check local user hardcoded into image you can go to /Home/LocalUsers and user ContainerAdminand password A123456!


8 thoughts on “ASP.NET core and integrated windows authentication in nanoserver container

  1. Pingback: Using Windows Authentication in ASP.NET core via HTTP.sys server | Various Tech notes

  2. I really enjoyed reading your posts about AD integration of ASP.NET and ASP.NET Core apps in Docker! We’re in the process of moving our ASP.NET Core app to Docker, but we’re running into issues with Windows authentication. Following your guide and the documentation at GitHub, I’ve managed to successfully authenticate clients from a domain-joined host, but then something strange happens: it seems there can only be 1 active session in the whole app!

    The domain-joined host is used for testing purposes, our app shows the currently logged in domain user. If I start 2 parallel mstsc sessions for 2 different users to the domain-joined hosts, both are authenticated using their Kerberos tickets but the last one to ‘log in’ to the app will determine what the other session’s username will show when the browser window is refreshed. Also, when accessing the app from a non-domain-joined host, there seems to be no authentication needed: the same username as on the domain-joined hosts is displayed, as if the user session is cached in IIS and is shared by all clients.

    I’ve stumbled across this article: If I turn this option off for Windows Authentication the app seems to respond better to authentication requests. Have you tried something similar? If you can, would you try out if you can reproduce this behavior?

    Also, when hosting the ASP.NET Core app in IIS, is it necessary to specify the IISOptions to the service, or is that only applicable if http.sys is used instead of IIS?

    Lastly, we’ve hit an issue when using routes.MapSpaFallbackRoute with a controller method with the [Authorize] attribute. It seems when falling back to NTLM (for non-domain joined hosts), the user session is not re-used for subsequent requests. The browser keeps asking for credentials for each separate HTTP request the browser makes. Have you encountered this before?


    • I’m not a developer but systems administrator so code samples which I provided might be either incomplete or erroneous. Point is to show that you can get windows authentication working inside container which is not actually part of AD. So issues you are experience with caching etc probably due to my coding skills rather then underlying issues with enabled integrated authentication.


      • Did you get to a bottom of this? I’m troubleshooting and trying to figure out if there is an issue but not seeing this behavior. To make sure you are not getting responses you shall not be expecting, use entirely different browser for second session (not just another Chrome window for example)


      • Yes, it turns out Traefik (which we use to make multiple instances of our Docker application stack) is not properly forwarding the authentication headers to the clients. Once we took Traefik out of the equation the sessions (including SSO) worked properly.

        One thing we see is that under Chrome there are seemingly random moments where the browser asks for a username/password, even if the user has provided that information only minutes ago. It may be a caching issue, we haven’t investigated further on this behavior.


  3. I suggest to test this code in proper Windows 2016 image without docker and see if it’s the same issue, if it is then issue with code, if not then with docker and I can investigate further.


  4. Microsoft have appeared to have broken the “credentialspec” parameter on running windows containers through docker on windows 10. No updates as of yet still waiting on resolution as of windows 10 version 1803. Any alternative ways of getting this working would be appreciated.

    Many Thanks


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s