I'm creating an ASP.NET Web API endpoint inside a console app which I need to host as a Windows Service.
Now everything is working except the endpoint is in http. I want to use https.
When I run it via Visual Studio.
I believe the Kestrel is behind an IIS as a reverse proxy and SSL certificates are validated. But when I host it as a Windows service. I'm getting certificate errors when trying to reach the endpoint
This is my Kestrel WebHost builder
var configigurations = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false)
.Build();
var host = new WebHostBuilder()
.UseKestrel(options =>
{
options.ListenAnyIP(443, listenOptions =>
{
listenOptions.UseHttps("sslcertificate.pfx", "ssl#123");
});
})
.UseUrls(config.ApiBaseUrl)
.UseConfiguration(configigurations)
.UseStartup<Startup>()
.Build();
host.Run();
Since it runs as a Windows service and exposes the API, I cannot rely on IIS. I need to configure for Kestrel.
But how can I
Generate an SSL for localhost (I'm using Windows)
If I have already an SSL certificate in production (*.cert). How can I make a *.pfx (cert + RSA private key) from it on production server (also Windows)
This will create a certificate
dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p crypticpassword
This will create a trust
dotnet dev-certs https --trust
.Net Core (and .Net 5) is bundled with a convenient tool to handle development self-signed certificates. Look into dotnet dev-certs. The commands are:
dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p crypticpassword
dotnet dev-certs https --trust
This doc also describes how to do the same thing with PowerShell or openssl if that's your style
Look into this question. In short, you can do that by exporting certificate from Windows Certificate store and choosing "Yes, export Private key" which automatically enabled PFX format
Related
I'm fumbling through my first exploration into docker containers with .NET. My local development environment is good to go - I've got my dev certs created and specified in my configuration file.
However, I'm trying to deploy to Azure Container Instances using a Caddy sidecar as a reverse-proxy. My application container fails on startup with the error: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date.
As far as I understand, I'll still need Kestrel, however the incoming traffic is no longer required to be HTTPS since it's being routed internally through the reverse-proxy.
I've tried tampering with my Startup.cs and Program.cs files to no avail. Can anyone point me in the right direction? Thanks.
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddMvc(options => { options.EnableEndpointRouting = false; });
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app
.UseStaticFiles()
.UseHsts()
.UseHttpsRedirection()
.UseMvc(routes => routes.MapRoute(name: "default", template: "{controller=App}/{action=Index}/{id?}"));
}
Program.cs
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseKestrel();
})
.ConfigureAppConfiguration(cb => { cb.AddEnvironmentVariables(); });
When the developer certs seems to had expired,
you can try running these
but initially Close your browsers so that they do not cache the certificates
On the commandline run
dotnet dev-certs https –clean
then run
dotnet dev-certs https -t a single time to create and trust a new development certificate.
Then please check the certificate with dotnet dev-certs https –verbose
and Restart VS
Reference: Unable to configure HTTPS endpoint- Wayne Thompson
You can try removing app.UseHttpsRedirection(); and adding UseHsts() as the way as you mentioned .
References:
Also please check this SO reference where kestrel configuration with urls is made.
docker - Unable to configure HTTPS endpoint for .net Core Kestral Server in Linux Container on Azure - Stack Overflow
I've created a WebAPI .Net 5 App which listens on an HTTPS port 8286. When I run it in Visual Studio everything is good.
Once I do "Publish" and try to run it on our Windows Server 2012 I get a "Unable to start Kestrel.
System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'..."
I have an SSL certificate installed on the server. It works with IIS and with a .NET 4.8 WebAPI Self hosted OWIN app
Using netsh http show sslcert I can see the certificate is bound
Here is my CreateHostBuilder function:
public static IHostBuilder CreateHostBuilder(string[] args)
{
Console.WriteLine("USE URLS: https://*:8286/");
return Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseUrls("https://*:8286/");
});
}
Okay so here is the solution when running the app from the command line (which uses the Kestrel Server)
You need to add to your appsettings.json the following section
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://*:1111"
}
,
"Https": {
"Url": "https://*:2222",
"Certificate": {
"Path": "my_ssl.pfx",
"Password": "my_password"
}
}
}}
Obviously for this to work you will need the pfx file. This will work even if you deploy to Linux.
BTW, if you add this to appsettings.json, it will override the ports in launchSettings.json when running from inside Visual Studio
My ASP.NET server was running fine on Friday. Today (Monday) I can't even start it. Error is:
crit: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to start Kestrel.
System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, Action`1 configureOptions)
at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
I have tried dotnet dev-certs https --trust many times to no avail. Each time it gives me the prompt to trust the certificate, each time with a different thumbprint.
... but nothing changes, the server still fails with the same error message. dotnet dev-certs https --check just says No valid certificate found. I have tried dotnet dev-certs https --clean which claims to succeed (but does not display any prompts), then dotnet dev-certs https --trust but still the same error when I start the server.
I have tried looking in the certificate manager in control panel (certmgr.msc) because doing so seemed to help someone else (on a different site) to solve the same error, but I have to admit I am none the wiser for having looked. Here's what shows up under Personal:
I have discovered that the server runs fine through IIS, running using the IIS profile from Visual Studio 2019. Ok, I could go adapt the client code to talk to a different TCP port, OR learn how to change the IIS server port (launchSettings.json right?).. but I would rather understand what has actually broken here, and learn how to fix it properly.
In case it helps, my Startup.Configure() says:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// for options and correct order, see https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.1
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
// app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
}
So:
How do I get a dev certificate into the default certificate location (wherever that is??) in a way that actually works? <-- my preferred fast solution today :/
Or, how do I create a dev certificate myself, and how do I tell my server where to find it?
Or, how do I make a real certificate (from my organisation's "official" certificate??) and then how do I use that to get client and server to actually check it, for good security? <-- my goal eventually, but I don't currently know enough yet to be able to do this - currently, my security comes from running client and server on a separate network.
Here's what finally worked for me.
The problem was that although the Certificate Manager was not showing any expired ASP.NET certificates, the Certificate Manager was only looking at the local machine store, not the user store.
I went to the Management Console (mmc from command line) and added a Snap-in for Certificates, for current user.
When I then ran that, I found a whole bunch of ASP.NET certificates under Personal / Certificates AND Trusted Root Certification Authorities / Certificates, some of them expired. I deleted all of them.
I then ran dotnet dev-certs https --trust again, and then my server started. Yay!
You need to delete all certificates issued for localhost, best way how to do it is with this Powershell script:
Get-ChildItem -Path Cert:\CurrentUser -Recurse `
| Where { $_.PSISContainer -eq $false } `
| Where { $_.Issuer -match 'localhost' } `
| Remove-Item;
Get-ChildItem -Path Cert:\LocalMachine -Recurse `
| Where { $_.PSISContainer -eq $false } `
| Where { $_.Issuer -match 'localhost' } `
| Remove-Item
After that you will be sure that all certificates issued for localhost are gone.
Then run
dotnet dev-certs https
That's it!
I am getting the net::ERR_CERT_AUTHORITY_INVALID error in ASP.NET Core when I try to request my Web API from an SPA.
The first solution to fix the issue was to go my ASP.NET Core address from browser Advanced - Proceed to localhost (unsafe) and after that the requests from my SPA would work. But I would have to repeat the procedure each time I am starting to work on my project.
Another solution I found was this. In a nutshell the solution is to run the command: dotnet dev-certs https --trust. I am on Windows, so according to the linked article On Windows it'll get added to the certificate store.
But after I run the command I am still getting the net::ERR_CERT_AUTHORITY_INVALID issue on requests. What could I do about it?
Running the command dotnet dev-certs https --trust will create a self-signed certificate in your device. This certificate will be issued to the localhost domain. In my case, after running it, the certificate was created but it was not added to "Trusted Root Certification Authorities".
To add the certificate, you will need to open certmgr.msc (win+r and run certmgr.msc), then go to "Personal" certificates and export the .cer certificate issued to localhost with the correct expiration time.
If you cannot find the certificate there, you can go to the browser and click on the not secure connection icon, then open the invalid certificate and go to the Details tab and click "Copy to File...", which should create also a .cer certificate.
Next, go to "Trusted Root Certification Authorities" and import the certificate there. Once that is done, the certificate will be valid in your local machine. You may need to restart the browser and the service.
In your application, add a reference to the Microsoft.AspNetCore.Authentication.Certificate via NuGet package. Then in the Startup.ConfigureServices method write this:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(
CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate();
// All other service configuration
}
Also add app.UseAuthentication(); in the Startup.Configure method. Otherwise, the HttpContext.User will not be set to ClaimsPrincipal
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
// All other app configuration
}
Source: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/certauth?view=aspnetcore-3.1
Do this in the order
dotnet dev-certs https --clean
Remove your keys and pem from AppData\Roaming\ASP.NET\https
dotnet dev-certs https --trust
Run SPA project with "start": "set HTTPS=true&&react-scripts start"
If you run your project(Point 4) before anything else. The authority is not trusted(done by 2) and results in authority invalid errors
I followed these steps and it didn't stop the "Not secure" message appearing in Chrome. So then I tried commenting the following line //app.UseHttpsRedirection(); in startup.cs in the Configure() method and it fixed the problem.
Update:
Just tried the official example https://github.com/aspnet/AspNetCore.Docs/tree/master/aspnetcore/fundamentals/servers/httpsys/samples/3.x/SampleApp and it doesn't work.
Brower message:
This site can’t provide a secure connection
localhost sent an invalid response.
Output:
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
User profile is available. Using 'C:\Users\xxx\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
warn: Microsoft.AspNetCore.Server.HttpSys.MessagePump[0]
Overriding address(es) 'https://localhost:5001, http://localhost:5000'. Binding to endpoints added to UrlPrefixes instead.
info: Microsoft.AspNetCore.Server.HttpSys.HttpSysListener[0]
Start
info: Microsoft.AspNetCore.Server.HttpSys.HttpSysListener[0]
Listening on prefix: http://localhost:5005/
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5005/
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: C:\Users\xxx\Downloads\AspNetCore.Docs-master\AspNetCore.Docs-master\aspnetcore\fundamentals\servers\httpsys\samples\3.x\SampleApp
I created a new Blazor application with Windows Authentication. (Visual Studio 2019 V16.4.0, .Net Core 3.1).
Now Windows Authentication works (the top right corner of the web page shows "Hello Domain\Username!") when running with IIS Express in Visual Studio. But Windows Authentication is not working when running as Kestrel application.
I followed the steps in the following link to make Windows Authentication work with Http.Sys. (BTW, I tried [Kestrel/Negotiate][1] but no luck)
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/httpsys?view=aspnetcore-3.1
Basically, it just adds the call of webBuilder.UseHttpSys() in CreateHostBuilder() in Program.cs.
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseHttpSys(options =>
{
options.AllowSynchronousIO = true;
options.Authentication.Schemes = AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
options.MaxConnections = null;
options.MaxRequestBodySize = 30000000;
// options.UrlPrefixes.Add("http://*:5005");
});
webBuilder.UseStartup<Startup>();
});
However, running the application will get an error page with message of
This site can’t be reached
The connection was reset.
or
This site can’t provide a secure connection
localhost sent an invalid response.
Edge's error messages are:
There was a temporary DNS error. Try refreshing the page.
Error Code: INET_E_RESOURCE_NOT_FOUND
IE error message:
Can’t connect securely to this page
This might be because the site uses outdated or unsafe TLS security settings. If this keeps happening, try contacting the website’s owner.
The solution is to relocate your certs, and do a bunch of manual configuration that doesn't seem like it should be necessary: I was following the Configure Windows Server section of the http.sys example fairly closely, but ran into issues with the netsh http sslcert commands. The problem is with where dotnet dev-certs https --trust installs the certificate! In What is the default location for certificates created using "dotnet dev-certs https" it's pointed out that that tool installs certificates in the current user's certificate store, not the local computer store. I had to add both certificate stores to mmc and copy the localhost cert over into Certificates (Local Computer)\Personal\Certificates, at which point the sslcert command completed, and when I ran the test application, it was successfully able to connect with TLS.