There are different web servers that can be used with a .NET Core Web Application:
- IIS Express (when pressing F5 in Visual Studio)
Supports NTLM, Negotiate (Kerberos)
Windows only
- IIS (when deploying to an IIS Folder)
Supports NTLM, 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 NTLM, Negotiate
Windows only
Windows authentication in IIS / IIS Express works without problems.
Kestrel can only use Negotiate (Kerberos). This means you need to setup a trusted connection with a service principle name (SPN). This can be done with the setspn command line tool. Unfortunally I have no experience in it because on a development machine you tend to skip that.
http.sys can use NTLM but is not compatible with IIS / IIS Express. This means you can't use Visual Studio debugging when using this. As a workarround you can add 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>();
});
As a sidenote, since .NET Core 3.0 there is a new interface "IHostBuilder" instead of "IWebHostBuilder" (only exists 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 runs in user mode and looks for the certificates at "CurrentUser\My". In constrast http.sys is kernel mode, which means the current user is not known. http.sys looks for the certificate at "LocalMachine\My".
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