在 ASP.NET Core 中配置 Windows 身份验证

通过Scott AddieLuke Latham

Windows 身份验证 (也称为协商、 Kerberos 或 NTLM 的身份验证) 可以配置为使用托管的 ASP.NET Core 应用IISKestrel,或HTTP.sys.

Windows 身份验证 (也称为协商、 Kerberos 或 NTLM 的身份验证) 可以配置为使用托管的 ASP.NET Core 应用IISHTTP.sys

Windows 身份验证依赖于操作系统的 ASP.NET Core 应用的用户进行身份验证。 使用 Active Directory 域标识或 Windows 帐户标识的用户在公司网络上运行你的服务器时,可以使用 Windows 身份验证。 Windows 身份验证是最适合于用户、 客户端应用程序和 web 服务器属于同一个 Windows 域的 intranet 环境。

备注

使用 HTTP/2 不支持 Windows 身份验证。 可以在 HTTP/2 响应发送身份验证质询,但客户端必须降级到 HTTP/1.1 之前进行身份验证。

IIS/IIS Express

添加身份验证服务通过调用AddAuthentication(Microsoft.AspNetCore.Server.IISIntegration命名空间) 中Startup.ConfigureServices:

services.AddAuthentication(IISDefaults.AuthenticationScheme);

启动设置 (调试器)

用于配置启动设置,只会影响Properties/launchSettings.json IIS express 文件,并不会配置 IIS 的 Windows 身份验证。 服务器配置中所述IIS部分。

Web 应用程序可通过 Visual Studio 或.NET Core CLI 的模板可以配置为支持 Windows 身份验证,这会更新Properties/launchSettings.json文件是自动的。

在修改现有项目,确认项目文件包含的包引用Microsoft.AspNetCore.App 元包 Microsoft.AspNetCore.Authentication NuGet 包。

IIS

IIS 使用ASP.NET Core 模块到承载 ASP.NET Core 应用程序。 Windows 身份验证配置为通过 IIS web.config文件。 以下部分介绍如何:

  • 提供本地web.config在部署应用时在服务器激活 Windows 身份验证的文件。
  • 使用 IIS 管理器配置web.config已部署到服务器的 ASP.NET Core 应用的文件。

如果尚未执行此操作,使 IIS 能够承载 ASP.NET Core 应用程序。 有关详细信息,请参阅 使用 IIS 在 Windows 上托管 ASP.NET Core

启用 Windows 身份验证的 IIS 角色服务。 有关详细信息,请参阅IIS 角色服务 (请参阅步骤 2) 中启用 Windows 身份验证

IIS 集成中间件默认配置为自动进行身份验证请求。 有关详细信息,请参阅与 IIS 的 Windows 上托管 ASP.NET Core:IIS 选项 (AutomaticAuthentication)

默认情况下,ASP.NET Core 模块配置为转发到应用的 Windows 身份验证令牌。 有关详细信息,请参阅ASP.NET Core 模块配置参考:AspNetCore 元素的特性

使用任一以下方法之一:

  • 发布和部署该项目之前, 添加以下web.config到项目根目录的文件:

    <?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>
    

    由.NET Core SDK 发布项目时 (而无需<IsTransformWebConfigDisabled>属性设置为true项目文件中),已发布web.config文件包括<location><system.webServer><security><authentication>部分。 有关详细信息<IsTransformWebConfigDisabled>属性,请参阅使用 IIS 在 Windows 上托管 ASP.NET Core

  • 发布和部署该项目之后, 执行服务器端配置使用 IIS 管理器:

    1. 在 IIS 管理器中,选择下的 IIS 站点站点的节点连接侧栏。
    2. 双击身份验证IIS区域。
    3. 选择匿名身份验证 选择禁用操作侧栏。
    4. 选择Windows 身份验证 选择启用操作侧栏。

    IIS 管理器时执行这些操作,会应用的修改web.config文件。 一个<system.webServer><security><authentication>使用更新的设置的添加节点anonymousAuthenticationwindowsAuthentication:

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

    <system.webServer>部分添加到web.config文件由 IIS 管理器是在应用外<location>发布应用时由.NET Core SDK 添加的部分。 因为部分添加之外<location>节点中,设置由任何继承子应用到当前应用。 若要阻止继承,将在添加<security>内的部分<location><system.webServer>.NET Core SDK 提供的部分。

    当使用 IIS 管理器添加 IIS 配置时,它只影响应用程序的web.config在服务器上的文件。 应用程序的后续部署可能会覆盖服务器上的设置,如果服务器的副本web.config替换为项目的web.config文件。 使用任一以下方法来管理的设置之一:

    • 使用 IIS 管理器中的设置重置web.config文件后部署上覆盖该文件。
    • 添加web.config 文件向本地使用的设置应用程序。

Kestrel

Microsoft.AspNetCore.Authentication.Negotiate NuGet 包可用于Kestrel以支持 Windows、 Linux 和 macOS 上使用 Negotiate、 Kerberos 和 NTLM 的 Windows 身份验证。

警告

凭据可以在连接上的请求之间得以保持。 协商身份验证不得使用代理中使用,除非代理维护与 Kestrel 1 对 1 连接关联 (持续性连接)。

备注

Negotiate 处理程序会检测基础服务器以本机方式支持 Windows 身份验证,并启用它。 如果服务器支持 Windows 身份验证,但它处于禁用状态,要求你启用服务器实现引发错误。 当服务器中启用 Windows 身份验证时,Negotiate 处理程序以透明方式将转发给它。

添加身份验证服务通过调用AddAuthentication(Microsoft.AspNetCore.Authentication.Negotiate命名空间) 和AddNegotitate(Microsoft.AspNetCore.Authentication.Negotiate命名空间) 中Startup.ConfigureServices:

services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
   .AddNegotiate();

通过调用添加身份验证中间件UseAuthenticationStartup.Configure:

app.UseAuthentication();

app.UseMvc();

中间件的详细信息,请参阅ASP.NET Core 中间件

允许匿名请求。 使用ASP.NET Core 授权质询的身份验证的匿名请求。

Windows 环境配置

Microsoft.AspNetCore.Authentication.Negotiate组件执行用户模式身份验证。 服务主体名称 (Spn) 必须添加到运行服务,而不是计算机帐户的用户帐户。 执行setspn -S HTTP/mysrevername.mydomain.com myuser管理命令行界面中。

Linux 和 macOS 的环境配置

中提供了有关在 Linux 或 macOS 计算机加入 Windows 域的说明Azure 数据 Studio 连接到 SQL Server 使用 Windows 身份验证的 Kerberos一文。 说明在域中创建的 Linux 计算机的计算机帐户。 必须将 Spn 添加到该计算机帐户。

备注

时中的指南Azure 数据 Studio 连接到 SQL Server 使用 Windows 身份验证的 Kerberos文章中,替换python-software-propertiespython3-software-properties必要。

一旦在 Linux 或 macOS 计算机加入到域,需要提供额外的步骤keytab 文件的 spn:

  • 在域控制器上,将添加到的计算机帐户的新的 web 服务的 Spn:
    • setspn -S HTTP/mywebservice.mydomain.com mymachine
    • setspn -S HTTP/mywebservice@MYDOMAIN.COM mymachine
  • 使用ktpass生成 keytab 文件:
    • ktpass -princ HTTP/mywebservice.mydomain.com@MYDOMAIN.COM -pass myKeyTabFilePassword -mapuser MYDOMAIN\mymachine$ -pType KRB5_NT_PRINCIPAL -out c:\temp\mymachine.HTTP.keytab -crypto AES256-SHA1
    • 某些字段必须以指定大写所示。
  • 将 keytab 文件复制到 Linux 或 macOS 计算机。
  • 选择通过环境变量的 keytab 文件: export KRB5_KTNAME=/tmp/mymachine.HTTP.keytab
  • 调用klist以显示当前可供使用的 Spn。

备注

Keytab 文件包含域访问凭据,必须相应地保护。

HTTP.sys

HTTP.sys支持内核模式 Windows 身份验证使用 Negotiate、 NTLM 或基本身份验证。

添加身份验证服务通过调用AddAuthentication(Microsoft.AspNetCore.Server.HttpSys命名空间) 中Startup.ConfigureServices:

services.AddAuthentication(HttpSysDefaults.AuthenticationScheme);

配置应用程序的 web 主机,以使用 Windows 身份验证使用 HTTP.sys (Program.cs)。 UseHttpSysMicrosoft.AspNetCore.Server.HttpSys命名空间。

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>()
                    .UseHttpSys(options =>
                    {
                        options.Authentication.Schemes = 
                            AuthenticationSchemes.NTLM | 
                            AuthenticationSchemes.Negotiate;
                        options.Authentication.AllowAnonymous = false;
                    });
            });
}
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();
}

备注

HTTP.sys 通过 Kerberos 身份验证协议委托给内核模式身份验证。 Kerberos 和 HTTP.sys 不支持用户模式身份验证。 必须使用计算机帐户来解密从 Active Directory 获取的并由客户端转发到服务器的 Kerberos 令牌/票证,以便对用户进行身份验证。 注册主机的服务主体名称 (SPN),而不是应用的用户。

备注

HTTP.sys 不支持 Nano Server 版本 1709年或更高版本上。 若要使用 Windows 身份验证和 HTTP.sys 与 Nano Server,使用Server Core (microsoft/windowsservercore) 容器 在 Server Core 上的详细信息,请参阅什么是 Windows Server 中的服务器核心安装选项?

为用户授权

匿名访问的配置状态确定的方式[Authorize][AllowAnonymous]应用中使用属性。 以下两个部分介绍如何处理的匿名访问权限的禁止和允许配置状态。

不允许匿名访问

启用 Windows 身份验证,并且禁用了匿名访问,则[Authorize][AllowAnonymous]特性不起作用。 如果 IIS 站点配置为不允许匿名访问,请求将永远不会到达该应用程序。 出于此原因,[AllowAnonymous]属性不适用。

允许匿名访问

启用 Windows 身份验证和匿名访问,使用[Authorize][AllowAnonymous]属性。 [Authorize]特性,您可以保护的应用程序的要求进行身份验证的终结点。 [AllowAnonymous]特性重写[Authorize]允许匿名访问的应用中的属性。 属性使用情况详细信息,请参阅ASP.NET Core 中的简单授权

备注

默认情况下,缺少授权可访问的页面的用户会显示 HTTP 403 响应为空。 StatusCodePages 中间件可以配置为向用户提供更好的"拒绝访问"体验。

Impersonation

ASP.NET Core 未实现模拟。 应用程序运行具有的所有请求,使用应用程序池或进程标识的应用的标识。 如果应用程序应执行代表用户操作,使用WindowsIdentity.RunImpersonated终端的内联中间件Startup.Configure 在此上下文中运行的单个操作,然后关闭上下文。

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 不支持异步操作,不应该用于复杂的方案。 例如,包装整个请求或中间件链不受支持或推荐的。

虽然Microsoft.AspNetCore.Authentication.Negotiate程序包可启用 Windows 上的身份验证,在 Windows 上仅支持 Linux 和 macOS 的模拟。

声明转换

使用 IIS,承载时AuthenticateAsync不在内部调用以初始化用户。 因此,默认情况下不激活每次身份验证后用于转换声明的 IClaimsTransformation 实现。 有关详细信息和激活声明转换的代码示例,请参阅ASP.NET Core 模块

承载与 IIS 进程内模式时AuthenticateAsync不在内部调用以初始化用户。 因此,默认情况下不激活每次身份验证后用于转换声明的 IClaimsTransformation 实现。 有关详细信息和托管进程中时将激活声明转换的代码示例,请参阅ASP.NET Core 模块

其他资源

上一篇:配置 ASP.NET Core 标识

下一篇:ASP.NET Core标识的自定义的存储提供程序

关注微信小程序
程序员编程王-随时随地学编程

扫描二维码
程序员编程王

扫一扫关注最新编程教程