Configure Windows Authentication in ASP.NET Core

By Scott Addie and Luke Latham

Windows Authentication can be configured for ASP.NET Core apps hosted with IIS or HTTP.sys.

Windows Authentication relies on the operating system to authenticate users of ASP.NET Core apps. You can use Windows Authentication when your server runs on a corporate network using Active Directory domain identities or Windows accounts to identify users. Windows Authentication is best suited to intranet environments where users, client apps, and web servers belong to the same Windows domain.

Enable Windows Authentication in an ASP.NET Core app

The Web Application template available via Visual Studio or the .NET Core CLI can be configured to support Windows Authentication.

Use the Windows Authentication app template for a new project

In Visual Studio:

  1. Create a new ASP.NET Core Web Application.
  2. Select Web Application from the list of templates.
  3. Select the Change Authentication button and select Windows Authentication.

Run the app. The username appears in the rendered app's user interface.

Manual configuration for an existing project

The project's properties allow you to enable Windows Authentication and disable Anonymous Authentication:

  1. Right-click the project in Visual Studio's Solution Explorer and select Properties.
  2. Select the Debug tab.
  3. Clear the check box for Enable Anonymous Authentication.
  4. Select the check box for Enable Windows Authentication.

Alternatively, the properties can be configured in the iisSettings node of the launchSettings.json file:

"iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": false,
    "iisExpress": {
        "applicationUrl": "http://localhost:52171/",
        "sslPort": 0
    }
}

When modifying an existing project, confirm that the project file includes a package reference for the Microsoft.AspNetCore.App metapackage or the Microsoft.AspNetCore.Authentication NuGet package.

Enable Windows Authentication with IIS

IIS uses the ASP.NET Core Module to host ASP.NET Core apps. Windows Authentication is configured for IIS via the web.config file. The following sections show how to:

  • Provide a local web.config file that activates Windows Authentication on the server when the app is deployed.
  • Use the IIS Manager to configure the web.config file of an ASP.NET Core app that has already been deployed to the server.

IIS configuration

If you haven't already done so, enable IIS to host ASP.NET Core apps. For more information, see Host ASP.NET Core on Windows with IIS.

Enable the IIS Role Service for Windows Authentication. For more information, see Enable Windows Authentication in IIS Role Services (see Step 2).

IIS Integration Middleware is configured to automatically authenticate requests by default. For more information, see Host ASP.NET Core on Windows with IIS: IIS options (AutomaticAuthentication).

The ASP.NET Core Module is configured to forward the Windows Authentication token to the app by default. For more information, see ASP.NET Core Module configuration reference: Attributes of the aspNetCore element.

Create a new IIS site

Specify a name and folder and allow it to create a new application pool.

Enable Windows Authentication for the app in IIS

Use either of the following approaches:

Development-side configuration with a local web.config file

Perform the following steps before you publish and deploy your project.

Add the following web.config file to the project root:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <security>
        <authentication>
          <anonymousAuthentication enabled="false" />
          <windowsAuthentication enabled="true" />
        </authentication>
      </security>
    </system.webServer>
  </location>
</configuration>

When the project is published by the SDK (without the <IsTransformWebConfigDisabled> property set to true in the project file), the published web.config file includes the <location><system.webServer><security><authentication> section. For more information on the <IsTransformWebConfigDisabled> property, see Host ASP.NET Core on Windows with IIS.

Server-side configuration with the IIS Manager

Perform the following steps after you publish and deploy your project.

  1. In IIS Manager, select the IIS site under the Sites node of the Connections sidebar.
  2. Double-click Authentication in the IIS area.
  3. Select Anonymous Authentication. Select Disable in the Actions sidebar.
  4. Select Windows Authentication. Select Enable in the Actions sidebar.

When these actions are taken, IIS Manager modifies the app's web.config file. A <system.webServer><security><authentication> node is added with updated settings for anonymousAuthentication and windowsAuthentication:

<system.webServer>
  <security>
    <authentication>
      <anonymousAuthentication enabled="false" />
      <windowsAuthentication enabled="true" />
    </authentication>
  </security>
</system.webServer>

The <system.webServer> section added to the web.config file by IIS Manager is outside of the app's <location> section added by the .NET Core SDK when the app is published. Because the section is added outside of the <location> node, the settings are inherited by any sub-apps to the current app. To prevent inheritance, move the added <security> section inside of the <location><system.webServer> section that the SDK provided.

When IIS Manager is used to add the IIS configuration, it only affects the app's web.config file on the server. A subsequent deployment of the app may overwrite the settings on the server if the server's copy of web.config is replaced by the project's web.config file. Use either of the following approaches to manage the settings:

  • Use IIS Manager to reset the settings in the web.config file after the file is overwritten on deployment.
  • Add a web.config file to the app locally with the settings. For more information, see the Development-side configuration section.

Publish and deploy your project to the IIS site folder

Using Visual Studio or the .NET Core CLI, publish and deploy the app to the destination folder.

For more information on hosting with IIS, publishing, and deployment, see the following topics:

Launch the app to verify Windows Authentication is working.

Enable Windows Authentication with HTTP.sys

Although Kestrel doesn't support Windows Authentication, you can use HTTP.sys to support self-hosted scenarios on Windows. The following example configures the app's web host to use HTTP.sys with Windows Authentication:

public class Program
{
    public static void Main(string[] args) => 
        BuildWebHost(args).Run();

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseHttpSys(options =>
            {
                options.Authentication.Schemes = 
                    AuthenticationSchemes.NTLM | AuthenticationSchemes.Negotiate;
                options.Authentication.AllowAnonymous = false;
            })
            .Build();
}

Note

HTTP.sys delegates to kernel mode authentication with the Kerberos authentication protocol. User mode authentication isn't supported with Kerberos and HTTP.sys. The machine account must be used to decrypt the Kerberos token/ticket that's obtained from Active Directory and forwarded by the client to the server to authenticate the user. Register the Service Principal Name (SPN) for the host, not the user of the app.

Note

HTTP.sys isn't supported on Nano Server version 1709 or later. To use Windows Authentication and HTTP.sys with Nano Server, use a Server Core (microsoft/windowsservercore) container. For more information on Server Core, see What is the Server Core installation option in Windows Server?.

Work with Windows Authentication

The configuration state of anonymous access determines the way in which the [Authorize] and [AllowAnonymous] attributes are used in the app. The following two sections explain how to handle the disallowed and allowed configuration states of anonymous access.

Disallow anonymous access

When Windows Authentication is enabled and anonymous access is disabled, the [Authorize] and [AllowAnonymous] attributes have no effect. If the IIS site (or HTTP.sys) is configured to disallow anonymous access, the request never reaches your app. For this reason, the [AllowAnonymous] attribute isn't applicable.

Allow anonymous access

When both Windows Authentication and anonymous access are enabled, use the [Authorize] and [AllowAnonymous] attributes. The [Authorize] attribute allows you to secure pieces of the app which truly do require Windows Authentication. The [AllowAnonymous] attribute overrides [Authorize] attribute usage within apps which allow anonymous access. See Simple Authorization for attribute usage details.

In ASP.NET Core 2.x, the [Authorize] attribute requires additional configuration in Startup.cs to challenge anonymous requests for Windows Authentication. The recommended configuration varies slightly based on the web server being used.

Note

By default, users who lack authorization to access a page are presented with an empty HTTP 403 response. The StatusCodePages middleware can be configured to provide users with a better "Access Denied" experience.

IIS

If using IIS, add the following to the ConfigureServices method:

// IISDefaults requires the following import:
// using Microsoft.AspNetCore.Server.IISIntegration;
services.AddAuthentication(IISDefaults.AuthenticationScheme);

HTTP.sys

If using HTTP.sys, add the following to the ConfigureServices method:

// HttpSysDefaults requires the following import:
// using Microsoft.AspNetCore.Server.HttpSys;
services.AddAuthentication(HttpSysDefaults.AuthenticationScheme);

Impersonation

ASP.NET Core doesn't implement impersonation. Apps run with the app's identity for all requests, using app pool or process identity. If you need to explicitly perform an action on behalf of a user, use WindowsIdentity.RunImpersonated in a terminal inline middleware in Startup.Configure. Run a single action in this context and then close the context.

app.Run(async (context) =>
{
    try
    {
        var user = (WindowsIdentity)context.User.Identity;

        await context.Response
            .WriteAsync($"User: {user.Name}\tState: {user.ImpersonationLevel}\n");

        WindowsIdentity.RunImpersonated(user.AccessToken, () =>
        {
            var impersonatedUser = WindowsIdentity.GetCurrent();
            var message =
                $"User: {impersonatedUser.Name}\t" +
                $"State: {impersonatedUser.ImpersonationLevel}";

            var bytes = Encoding.UTF8.GetBytes(message);
            context.Response.Body.Write(bytes, 0, bytes.Length);
        });
    }
    catch (Exception e)
    {
        await context.Response.WriteAsync(e.ToString());
    }
});

RunImpersonated doesn't support asynchronous operations and shouldn't be used for complex scenarios. For example, wrapping entire requests or middleware chains isn't supported or recommended.

Claims transformations

When hosting with IIS in-process mode, AuthenticateAsync isn't called internally to initialize a user. Therefore, an IClaimsTransformation implementation used to transform claims after every authentication isn't activated by default. For more information and a code example that activates claims transformations when hosting in-process, see ASP.NET Core Module.