Using Windows Authentication in ASP.NET core via HTTP.sys server

 

Previous article ASP.NET core and integrated windows authentication in nanoserver container showed how to use integrated Windows authentication in docker windows container via IIS which requires a lot of prep steps and pretty cumbersome to implement. Another option is to use WebListener which as renamed to HTTPSYS in ASP.NET core version 2.0. Solution is hosted in following Github repo https://github.com/artisticcheese/ContainerWindowsAuth.

You have to prepare your Windows AD environment as per this Enabling integrated Windows Authentication in windows docker container article as a prerequisite.

You startup.cs file shall have following entry in ConfigureServices method which will enable both anonymous and Windows Authenticated access.

services.AddAuthentication(Microsoft.AspNetCore.Server.HttpSys.HttpSysDefaults.AuthenticationScheme);

Your Program.cs need following entry in BuildWebHost method

This will allow to use both Windows and Anonymous authentication side by side. Now your home controller can specify which actions will require authentication and which not as per below.

Dockerfile below is using multi stage build and publish process

Final step is to run built image on Container host which was prepped earlier

docker run -d -h containerhost –security-opt “credentialspec=file://win.json” -p 8888:80 artisticcheese/winauth:nano-httpsys

Accessing this URL from domain joined machine via name only will not require users entering password and will automatically log them in, accessing via IP address will prompt for password and will allow login, accessing action which does not require authentication as expected will not require password. See below.

vmconnect_2017-09-10_16-03-41

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 (https://github.com/artisticcheese/ContainerWindowsAuth)

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. http://192.168.1.235:88/Home/Windows, 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!

vmconnect_2017-09-13_11-48-14

Using multistage docker build to create IIS + ASP.NET Core image + nanoserver

Kestrel webserver (server which serves ASP.NET core exe) does not support integrated Windows authentication and requires external proxy server to handle this. One of the those proxy servers is IIS. Problem is that there is no docker image provided by Microsoft which have IIS + ASP.NET core + nanoserver. Further complicating things are the fact that there is no easy and straightforward way to install IIS on nanoserver image which has ASP.NET core, neither it’s easy to install ASP.NET core on IIS image build on nanoserver. There is multitude articles and script which are doing little parts here and there but none provide complete solution in part due to requirement to have ASP.NET core module to be first installed on full server core image before DLLs can be extracted for use in nanoserver IIS image.

Thanks to 17.05 docker options to build multistage image this entire pretty easily accomplished with single docker file.

Dockerfile below is using 2 middleware images to pull relevant files into final image which contains ASP.NET core + IIS on top of nanoserver.

Image microsoft/aspnetcore:2.0.0-nanoserver  is used for extraction of .NET core installation.

Image microsoft\iis based off WindowsServerCore is used to install .NET core webhosting package (EXE which upon execution places required ASP.NET core module and schema into middleware container) and later extract 2 necessary files (module itself and schema file) to be used in final image.

Final image is built from 2 middleware images above with some additional configuration necessary for ASP.NET core module to work in IIS and path to DOTNET core is added to environment Path variable.

Enabling integrated Windows Authentication in windows docker container

Walk through below will enable integrated Windows Authentication for windows docker container in Active Directory environment.

Overview of steps are below

  1. Create Global Security group Container Hosts  in Active Directory
  2. Add container host servers to group which is allowed to decrypt password GMSA account
  3. Reboot container host so computer account have proper group membership
  4. Create GMSA account in Active Directory
  5. Install GMSA account on container host
  6. Add SPN record to GMSA account
  7. Generate credentialspecs file to be passed to docker daemon during container startup
  8. Launch docker container with proper parameters

Detailed implementation steps are below

Create Global Security group Container Hosts  in Active Directory

vmconnect_2017-09-09_14-35-19

Add computer account for container host to Container Hosts group

vmconnect_2017-09-09_14-52-30

Reboot container host computer

This step is required so computer account will have proper AD group associated with it

Create GMSA account in Active Directory

On domain controller execute

Install GMSA account on container host and test it

Output shall not contain any errors and will look like below

Path : 
Online : True
RestartNeeded : False

DistinguishedName : CN=containerhost,CN=Managed Service Accounts,DC=ad,DC=local
Enabled : True
Name : containerhost
ObjectClass : msDS-GroupManagedServiceAccount
ObjectGUID : 12941984-5fd3-4095-96f9-cbd96902eb36
SamAccountName : containerhost$
SID : S-1-5-21-3914853822-719528391-929614657-1606
UserPrincipalName :

True

Add SPN record to GMSA account

This step is required if for kerberos authentication to work and for automatic login in Chrome/IE. Without it authentication will still work but will always prompt for username/password since it will fallback to NTLM.

Launch adsiedit.msc on domain controller and add SPN of HTTP/containerhost1.ad.local to GMSA account

vmconnect_2017-09-09_15-05-23

Generate credentialspecs file to be passed to docker daemon during container startup

Execute powershell below to generate your GMSA configuration file which will be used by docker to enable Windows Authentication

 

Launch docker container with proper parameters

Launching docker with parameters specifying GMSA account name as well as credential specs file

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

You can use my image artisticcheese/winauth:servercore to test if this solution works. Image has just plain vanilla IIS with windows authentication enabled and default page showing which account are you logged on with. This image is based of 1709 version of Windows Server Core and hence make sure your host is above 1709​.

Now if you access your container host on port 8080 on any domain joined machine you shall be automatically authenticated. If you try to access your containerhost via IP address then you will be prompted for username/password since IE/chrome will assume you are accessing external computer and hence will not automatically log you on.

vmconnect_2017-09-09_19-46-09