Windows 服务中托管的 Kestrel 的 Windows 身份验证

San*_*ndy 12 .net windows-services kestrel-http-server asp.net-core

我正在运行托管在 Windows 服务中的 ASP.NET Core 应用程序,如下所述:

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-2.1

我需要此应用程序来支持 Windows 身份验证。我有哪些选择?我尝试在 IIS 中使用应用程序请求路由/URL 重写模块作为 Windows 身份验证的反向代理,但无法弄清楚如何使其工作。任何指导将不胜感激。

Gre*_*ana 16

.NET Core Web 应用程序可以使用不同的 Web 服务器:

  • IIS Express(在 Visual Studio 中按 F5 时)仅
    支持 NTLM、协商 (Kerberos)
    Windows
  • IIS(部署到 IIS 文件夹时)
    支持 NTLM,
    仅协商Windows
  • Kestrel(使用“dotnet run”或从命令行执行时)
    支持协商(使用 nuget 包,请参阅 Yush0s 回复)
    Windows / Linux
  • http.sys(类似于 kestrel,但在 Startup.cs 中配置)
    支持 NTLM,
    仅协商Windows

IIS / IIS Express 中的 Windows 身份验证可以正常工作。

Kestrel 只能使用协商 (Kerberos)。这意味着您需要使用服务主体名称 (SPN) 设置可信连接。这可以通过 setspn 命令行工具来完成。不幸的是,我没有这方面的经验,因为在开发机器上你往往会跳过它。

http.sys 可以使用 NTLM,但与 IIS / IIS Express 不兼容。这意味着您在使用它时不能使用 Visual Studio 调试。作为一种解决方法,您可以添加一个环境变量来决定是否使用 http.sys。例如,将以下行添加到 launchSettings.json 中的“Project”配置文件:

  "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development",
    "USE_HTTP_SYS": "true"
  }
Run Code Online (Sandbox Code Playgroud)

现在可以有条件地使用 http.sys 或不使用:

 public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>
        {
            if (bool.Parse(Environment.GetEnvironmentVariable("USE_HTTP_SYS") ?? "false"))
            {
                webBuilder.UseHttpSys(options =>
                {
                    options.Authentication.Schemes = AuthenticationSchemes.NTLM;
                    options.Authentication.AllowAnonymous = false;
                });
            }

            webBuilder.UseStartup<Startup>();
        });
Run Code Online (Sandbox Code Playgroud)

作为旁注,从 .NET Core 3.0 开始,有一个新接口“IHostBuilder”而不是“IWebHostBuilder”(仅存在于向后兼容性)。


遗憾的是,当您使用“dotnet run”并转到该网站时,您可能会看到一条错误消息:

  • Internet Explorer:无法安全地连接到此页面
  • Chrome:无法访问此网站
  • 火狐:无法连接

Kestrel 带来了它自己的证书管理。它在用户模式下运行并在“CurrentUser\My”中查找证书。相比之下,http.sys 是内核模式,这意味着当前用户是未知的。http.sys 在“LocalMachine\My”中查找证书。

因为http.sys 不知道端口上使用的是哪个证书,所以你还需要将证书分配给.net 应用程序的https 端口。这需要以本地管理员身份通过 PowerShell 完成:

  "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development",
    "USE_HTTP_SYS": "true"
  }
Run Code Online (Sandbox Code Playgroud)

请注意,"CN=localhost" 是 uri,"0.0.0.0:5001" 是 dotnet 应用程序的端口,appid 是随机标识符(如果您的应用程序有一个 guid,您也可以使用它,但这不是必需的) .

如果您没有证书(例如用于开发),您可以为机器创建一个自签名证书(需要 Win10 和管理员权限):

 public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>
        {
            if (bool.Parse(Environment.GetEnvironmentVariable("USE_HTTP_SYS") ?? "false"))
            {
                webBuilder.UseHttpSys(options =>
                {
                    options.Authentication.Schemes = AuthenticationSchemes.NTLM;
                    options.Authentication.AllowAnonymous = false;
                });
            }

            webBuilder.UseStartup<Startup>();
        });
Run Code Online (Sandbox Code Playgroud)


Yus*_*sh0 14

使用 .Net Core 3.0,您可以将 Windows 身份验证与 Kestrel 结合使用。它有一个 Nuget 包:Microsoft.AspNetCore.Authentication.Negotiate

然后你可以在 Startup.ConfigureServices 中添加它:

services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
   .AddNegotiate();
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅:https :
//docs.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-3.0&tabs=visual-studio#kestrel


Gab*_*uci 3

Microsoft 有一篇关于ASP.NET Core 中的 Windows 身份验证的完整文章,其中有一节描述了如何在没有 IIS 的情况下进行身份验证Kestrel 不支持 Windows 身份验证更新:现在支持),因此您必须使用 HTTP.sys 进行托管。乍一看很简单(在您的 Program.cs 中):

.UseHttpSys(options =>
{
    options.Authentication.Schemes = 
        AuthenticationSchemes.NTLM | AuthenticationSchemes.Negotiate;
    options.Authentication.AllowAnonymous = false;
})
Run Code Online (Sandbox Code Playgroud)

直到您意识到还有另一篇关于 HTTP.sys 中托管的文章,因此您可能会发现其他一些原因,它可能会破坏其他内容。

将其托管在 IIS(而不是 Windows 服务)中并让 IIS 处理 Windows 身份验证可能会更容易。

您最初决定托管 Windows 服务有什么原因吗?

  • 如果这变得太有问题,您可以拆分应用程序:使用 Windows 服务作为后台进程,并使用 IIS 中托管的单独 Web 应用程序作为前端。 (2认同)