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

时间:2018-12-19 00:26:45

标签: .net asp.net-core windows-services kestrel-http-server

我正在运行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身份验证的反向代理,但无法弄清楚如何使它工作。任何指导将不胜感激。

3 个答案:

答案 0 :(得分:3)

Microsoft有整篇关于Windows Authentication in ASP.NET Core的文章,包括section describing how to do it without IIS。 Kestrel不支持Windows身份验证,因此您必须托管HTTP.sys。首先看起来很简单(在Program.cs中):

.UseHttpSys(options =>
{
    options.Authentication.Schemes = 
        AuthenticationSchemes.NTLM | AuthenticationSchemes.Negotiate;
    options.Authentication.AllowAnonymous = false;
})

直到您意识到存在whole other article about hosting in HTTP.sys,因此您可能会发现其他可能破坏其他内容的原因。

host it in IIS(而不是Windows服务)和let IIS handle the Windows Authentication可能更容易。

您是否有理由首先决定托管Windows服务?

答案 1 :(得分:2)

通过.Net Core 3.0,您可以将Windows身份验证与Kestrel一起使用。有一个Nuget软件包:Microsoft.AspNetCore.Authentication.Negotiate

然后您可以将其添加到Startup.ConfigureServices:

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

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

答案 2 :(得分:2)

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

  • IIS Express(在Visual Studio中按F5时)
    支持NTML,协商(Kerberos)
    仅Windows
  • IIS(在部署到IIS文件夹时)
    支持HTML,协商
    仅Windows
  • 红est(使用“ dotnet run”或从命令行执行时)
    支持协商(带有nuget程序包,请参见Yush0s的回复)
    Windows / Linux
  • http.sys(类似于红est,但已在Startup.cs中配置)
    支持NTML,协商
    仅Windows

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

红est只能使用协商(Kerberos),这意味着您需要一个受信任的连接。这意味着您需要使用setspn命令行工具设置服务主体名称(SPN)。我从来没有做过这个主要工作,因为我主要在开发计算机上工作,而不是在目标服务器上工作。

http.sys可以使用NTML,但与IIS / IIS Express不兼容,因此在开发过程中无法在Visual Studio中使用它。解决方案可以是决定是否使用http.sys的环境变量。例如,将以下行添加到launchSettings.json中的“项目”配置文件中:

  "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development",
    "USE_HTTP_SYS": "true"
  }

现在可以有条件地使用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>();
        });

请注意,.NET 3.0使用“ IHostBuilder”代替“ IWebHostBuilder”,后者仅在.NET 3.0中存在,以实现向后兼容。


不幸的是,当您使用“ dotnet run”并转到网站时,您可能会看到错误消息:

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

Kestrel带来了自己的证书管理。它使用来自“ CurrentUser \ My”的证书。相反,http.sys是内核模式,这意味着需要将证书放在“ LocalMachine \ My”中才能使用。

由于http.sys不知道端口上使用了哪个证书,因此还需要将证书分配给.net应用程序的https端口。这需要通过PowerShell作为本地管理员来完成:

$cert = Get-ChildItem -Path Cert:\LocalMachine\My | Where { $_.Subject -eq "CN=localhost" } | Select -First 1
netsh http add sslcert ipport=0.0.0.0:5001 appid='{12345678-1234-43f8-a778-f05f3c6b9709}' certhash=$($cert.Thumbprint)

请注意,“ CN = localhost”是uri,“ 0.0.0.0:5001”是dotnet应用程序的端口,而appid是随机标识符(如果您的应用程序有GUID,您也可以使用它,但是不需要)。

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

$rootextension = [System.Security.Cryptography.X509Certificates.X509BasicConstraintsExtension]::new($true, $true, 0, $true)
$cert = New-SelfSignedCertificate -Subject "CN=localhost" -FriendlyName "Development localhost Certificate" -Extension $rootextension -NotAfter ([DateTime]::Now).AddYears(10) -KeyUsage DigitalSignature,KeyEncipherment,DataEncipherment -CertStoreLocation "Cert:\LocalMachine\My" -KeyExportPolicy Exportable