Windows Authentication for Kestrel hosted in Windows service

穿精又带淫゛_ 提交于 2019-12-07 14:11:58

问题


I am running an ASP.NET Core application hosted in a Windows service as described here:

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

I need this application to support Windows Authentication. What are my options? I tried using Application Request Routing / URL Rewrite module in IIS as a reverse proxy with Windows Authentication but could not figure out how to make that work. Any guidance would be appreciated.


回答1:


Microsoft has a whole article about Windows Authentication in ASP.NET Core, including a section describing how to do it without IIS. Kestrel doesn't support Windows Authentication, so you have to host with HTTP.sys. It looks easy at first (in your Program.cs):

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

Until you realize that there's a whole other article about hosting in HTTP.sys, so you may find some other reasons it might break something else.

It might be easier to host it in IIS (instead of a Windows Service) and let IIS handle the Windows Authentication.

Is there a reason you decided to host in a Windows Service in the first place?




回答2:


With .Net Core 3.0 you can use Windows Authentication with Kestrel. There is a Nuget Package for it: Microsoft.AspNetCore.Authentication.Negotiate

You then can add it in Startup.ConfigureServices:

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

For more Information also see:
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-3.0&tabs=visual-studio#kestrel




回答3:


There are different web servers that can be used with a .NET Core Web Application:

  • IIS Express (when pressing F5 in Visual Studio)
    Supports NTML, Negotiate (Kerberos)
    Windows only
  • IIS (when deploying to an IIS Folder)
    Supports HTML, Negotiate
    Windows only
  • Kestrel (when using "dotnet run" or executing from the command line)
    Supports Negotiate (with a nuget package, see Yush0s reply)
    Windows / Linux
  • http.sys (Like kestrel but configured in the Startup.cs)
    Supports NTML, Negotiate
    Windows only

Windows authentification in IIS / IIS Express seems to be working like it should.

Kestrel can only use Negotiate (Kerberos), this means you need a trusted connection. This means you need to setup a service principle name (SPN) with the setspn command line tool. I never done this primary because I'm working primary on my development machine and not the target server.

http.sys can use NTML but is not compatible with IIS / IIS Express, so using this in Visual Studio while developing does not work. A solution can be an environment variable that decides to use http.sys or not. For example add the following line to the "Project" profile in the launchSettings.json:

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

Now it's possible to conditional use http.sys or not:

 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>();
        });

Please note that .NET 3.0 uses "IHostBuilder" instead of "IWebHostBuilder" which only exists in .NET 3.0 for backward compatibility.


Sadly, when you use "dotnet run" and goto the website you might see an error message:

  • Internet Explorer: Can't connect securely to this page
  • Chrome: This site can't be reached
  • Firefox: Unable to connect

Kestrel brings it's own certificate management. It uses the certificates from "CurrentUser\My". In contrast http.sys is kernel mode, which means that the certificates need to be placed in "LocalMachine\My" to be used.

Because http.sys doesn't know which certificate is used on the port, you also need to assign the certificate to the https port of the .net application. This needs to be done via PowerShell as a local administrator:

$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)

Note that "CN=localhost" is the uri, "0.0.0.0:5001" is the port of the dotnet app and the appid is a random identifier (if your app has an guid you can use that too, but it's not required).

If you don't have a certificate (e.g. for development) you might create a self signed certificate for the machine (Win10 and admin right required):

$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


来源:https://stackoverflow.com/questions/53842990/windows-authentication-for-kestrel-hosted-in-windows-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!