4

I'm trying to create a asp.net core web app that runs on docker and has windows authentication, by following the steps on this answer.

I've uploaded the project to google drive, in case you want to download it: google drive link

Project Info:

  • ASP.Net core web app
  • .net 5.0 framework
  • windows authentication
  • docker support (linux)
  • Created with Visual Studio 2019 community (16.10.2) on windows 10.

My Steps:

  • Added HomeController + views
  • Installed Microsoft.AspNetCore.Authentication.Negotiate package
  • Added services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate(); to ConfigureServices
  • Added app.UseAuthentication(); to Configure

Behavior (debug mode, docker):

I could enter the application without entering my credentials and User.Identity.Name was null. I added the Microsoft.AspNetCore.Authorization.AuthorizeAttribute attribute on the home controller, so now I can enter my credentials, but once I do get the following error:

GssApiException: GSSAPI operation failed with error - Unspecified GSS failure. Minor code may provide more information (Keytab FILE:/etc/krb5.keytab is nonexistent or empty).

Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler.HandleRequestAsync() Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler.HandleRequestAsync() Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

I'm not sure what the problem is (or if this is the correct approach to begin with), so I would appreciate some points on how to do this. I've included the relevant files of the project below.

Startup.cs

using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace DockerTest {
    public class Startup {
        public Startup(IConfiguration configuration) {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services) {
            services.AddRazorPages();
            services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
            app.UseDeveloperExceptionPage(); // removed other case to save space

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

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

            app.UseEndpoints(endpoints => {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

Program.cs

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace DockerTest {
    public class Program {
        public static void Main(string[] args) {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
    }
}

HomeController.cs

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace DockerTest.Controllers {
    [Route("[controller]")]
    [Authorize]
    public class HomeController : Controller {
        [Route("/")]
        [Route("/Home")]
        [Route("/Home/Index")]
        public IActionResult Index() {
            return View();
        }
    }
}

DockerFile (as created by vs)

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

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

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

FROM build AS publish
RUN dotnet publish "DockerTest.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "DockerTest.dll"]
nick zoum
  • 7,216
  • 7
  • 36
  • 80
  • https://stackoverflow.com/a/68133438/5298150 – abdusco Aug 03 '21 at 17:41
  • @abdusco Can't say I fully understand your answer, but debugging on IIS express mode works fine, debugging on docker mode is the problematic one. – nick zoum Aug 03 '21 at 17:48
  • The problem is that your app needs to have 1-1 connection affinity for windows auth to work. that means you need to enable ntlm auth mode in whichever reverse proxy you're using (apart from iis, and kestrel). caddy has a module, nginx has a commercial module, not sure about the others. – abdusco Aug 03 '21 at 18:29
  • @abdusco I'm just using the vs debugger, it works fine for iis express but I when I try to switch to the docker debugger I get the error i've posted in the question. So is this something I have to change in `DockerFile`? – nick zoum Aug 03 '21 at 20:23
  • 1
    It'll work fine in debug mode under IIS as Window Integrated Security is enabled on a Windows machine. Problem is running the web app on Linux that doesn't natively support ntlm. Kestral isn't a full blown web server and you have to setup a reverse proxy for example to NGINX, see step 9 here to get a drift of what we're saying: https://github.com/MeaningOfLights/AzureTraining/blob/master/Hands-On-Labs-That-Work/73-Docker-3-WebForK8.md – Jeremy Thompson Aug 09 '21 at 01:23
  • 3
    The Microsoft.AspNetCore.Authentication.Negotiate package allows ASP.NET Core to authenticate using kerberos but you also have to install and configure Kerberos in your Linux container and add some SPN to your domain (I don't know if your development environment let you do that). See https://learn.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-5.0&tabs=visual-studio#kestrel You can also have a look here : https://stackoverflow.com/questions/60296237/windows-authentication-in-linux-docker-container – GRFRM Aug 09 '21 at 12:37
  • @GRFRM Right now I'm just trying to make it work in Docker debug mode, but eventually it's supposed to work on a linux server (that doesn't have kerberos). So isn't it possible to make it work with ntlm instead of kerberos? – nick zoum Aug 12 '21 at 13:38
  • Apparently, ntlm is not supported by Kestrel on Linux (only Windows). Read here : https://github.com/dotnet/aspnetcore/issues/14951 – GRFRM Aug 13 '21 at 12:37

0 Answers0