Asp.net-core – Asp.Net Core Windows Authentication Not Working in IIS

.net coreactive-directoryasp.net-coreiiswindows-authentication

Asp.Net Core doesn't seem to recognize the user from the call context?.User?.Identity?.Name when windows authentication is enabled and running in IIS Express or IIS.

Desired behavior: Enabling both Windows authentication and anonymous authentication in IIS and/or IIS Express, Asp.Net Core should automatically recognize the windows user.

Actual behavior: When I enable both windows and anonymous authentication in IIS or IIS Express, the user name is null. When I disable anonymous authentication or call HttpContext.ChallengeAsync(IISDefaults.AuthenticationScheme), I get a login prompt, which I don't want.

My understanding is that, even though I want to use this for Active Directory, I don't need active directory or a domain to authenticate a windows user.

Environment:

  • Windows 8.1 (not on a domain)
  • IIS 8.5 / Visual Studio 2017 w/ IIS Express
  • Windows Authentication security feature installed
  • Windows Authentication & (with NTLM provider) & Anonymous Authentication Enabled
  • Logged in as local account user

Dependencies:

  • Microsoft.AspNetCore.All 2.0.8

Startup:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<IISOptions>(iis =>
    {
        iis.AuthenticationDisplayName = "Windows";
        iis.AutomaticAuthentication = true;
    });

    services.AddAuthentication(IISDefaults.AuthenticationScheme);
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseAuthentication();
    app.Run(async (context) =>
    {
        await context.Response.WriteAsync(JsonConvert.SerializeObject(new
        {                
            UserName = context?.User?.Identity?.Name
        }));
    });       

launchSettings.json:

{
  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:51682/",
      "sslPort": 0      
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <remove name="aspNetCore" />
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
    </handlers>
    <aspNetCore forwardWindowsAuthToken="true" processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" />
  </system.webServer>
</configuration>

applicationhost.config: (IIS Express)

Based on this article: https://docs.microsoft.com/en-us/iis/configuration/system.webServer/security/authentication/windowsAuthentication/

<authentication>
  <anonymousAuthentication enabled="true" userName="" />
  <basicAuthentication enabled="false" />
  <clientCertificateMappingAuthentication enabled="false" />
  <digestAuthentication enabled="false" />
  <iisClientCertificateMappingAuthentication enabled="false"></iisClientCertificateMappingAuthentication>
  <windowsAuthentication enabled="true">
    <providers>
      <add value="NTLM" />
    </providers>
  </windowsAuthentication>
</authentication>

Best Answer

A couple things:

  1. When you disable anonymous authentication, you get a popup because the browser likely doesn't trust the site. You need to open Internet Options (from the Windows Control Panel) -> Security tab -> Click 'Trusted Sites' -> Click 'Sites' and add the URL to your site there. Both IE and Chrome use those settings for deciding whether to automatically send your credentials.

  2. When you have both anonymous and Windows authentication enabled, anonymous takes precedence except in places where you tell it that the user must be logged in. To do that, use the [Authorize] attribute either on a controller, or just on individual actions. There are more details in the documentation, under the heading Allow Anonymous Access.

Related Topic