Enabling TLS1.2 or TLS1.3 in c# asp.net core 3.1 - asp.net-core

I am building a web app using asp.net core 3.1.
I want to enable TLS1.2 (or TLS1.3 if it works and is backward compatible.)
I have a web site running under IIS Express that is failing the SSL certificate.
The console shows the following error:
I followed some instructions and I thought I could solve the problem by executing the following code in CreateHostBuilder in Program.cs:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel(s => {
s.ConfigureHttpsDefaults(k =>
{
k.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
});
}).UseStartup<Startup>();
});
I have run the application and it is still failing with the same error.
I am also running an implementation of IdentityServer4 on my local machine. That does not seem to have the same problem.
The identityserver4 site is secure.
How do I force my site to use TLS1.2 (or later)?

You can set the supported TSL protocols here:
webBuilder.UseKestrel((context, serverOptions) =>
{
serverOptions.AddServerHeader = false;
serverOptions.Listen(IPAddress.Any, 80);
serverOptions.Listen(IPAddress.Any, 443,
options =>
{
var cert = ...Load TLS certificate;
options.UseHttps(serverCertificate: cert, configureOptions: httpsOptions =>
{
httpsOptions.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13;
});
});
});
See also
https://github.com/dotnet/aspnetcore/issues/22563
https://karthiktechblog.com/aspnetcore/how-to-use-tls-1-2-in-asp-net-core-2-0-and-above

Related

How to resolve ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITY for self hosted signalR?

I'm trying to host a SignalR hub in a .NET Core 3.1 Windows Service, and when my client begins negotiation it fails with the response net::ERR_HTTP2_INADEQUATE_TRANSPORT_SECURITY
My SSL certificate is successfully loaded, and it checks out as valid in browser on port 443, but when browsing to my alternate port (randomly selected 12457) the browser does not consider it valid
If I switch down to HTTP1, I get a 405 I suspect from incompatibility with the client (microsoft/angular).
Here's how I'm configuring with my SSL certificate
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseUrls(configuration.GetValue<string>("ListenerEndpoint"));
webBuilder.UseKestrel(options =>
{
options.Listen(IPAddress.Any, 12457, listenOptions =>
{
listenOptions.UseHttps(options =>
{
var certificateStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine, OpenFlags.ReadOnly);
var certificates = certificateStore.Certificates.Find(X509FindType.FindByThumbprint, "<thumbprint>", true);
var certificate = certificates[0];
options.ServerCertificate = certificate;
});
});
});
});
I've followed the netsh command to expose the cert on this port per: https://weblog.west-wind.com/posts/2013/Sep/23/Hosting-SignalR-under-SSLhttps#:~:text=Even%20if%20your%20self-hosted%20SignalR%20application%20doesn%27t%20explicitly,that%20will%20reject%20mixed%20content%20on%20SSL%20pages. without a positive effect

Microsoft.AspNetCore.Authentication.OpenIdConnect /oauth2/authorize endpoint form - redirect_uri error

I have an application (.NET 5.0 ASP Net Core) application that I am trying to deploy to an AWS Amazon Linux 2 server. It appears that all aspects of deployment are fine except for authorization with AWS Congnito and Microsoft.AspNetCore.Authentication.OpenIdConnect. Everything works fine in dev/local and the problems only exhibit themselves when in prod deployment.
The issue exhibits itself as an "An error was encountered with the requested page." at https://auth.<mydomain>.com/error?error=redirect_mismatch&client_id=<myclientid> in the Hosted UI when trying to login. I have confirmed and reconfirmed that the Callback URL(s) are set correctly: https://sub.domain.com/signin-oidc, https://localhost:5001/signin-oidc.
My app is running on http://localhost:5000 behind an apache reverse proxy. I suspect that the non-HTTPS portion of the path between Apache and Kestrel is the issue.
What I have noticed is that Microsoft.AspNetCore.Authentication.OpenIdConnect is lacking https in the redirect_uri value that it creates as part of the /oauth2/authorize endpoint it calls.
This is what I see in Dev (no issues):
This is what I see when deployed, note that the redirect_uri is http:
In the App client settings, I can't set the signin-oidc endpoint to use the HTTP.
My ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.ResponseType = "code";
options.ResponseType = Configuration["Authentication:Cognito:ResponseType"];
options.MetadataAddress = Configuration["Authentication:Cognito:MetadataAddress"];
options.ClientId = Configuration["Authentication:Cognito:ClientId"];
options.TokenValidationParameters = new TokenValidationParameters
{
RoleClaimType = "cognito:groups"
};
options.Events = new OpenIdConnectEvents
{
OnTicketReceived = e =>
{
e.ReturnUri = string.Format("/Home/CheckProfile?url={0}", HttpUtility.UrlEncode(e.ReturnUri));
return Task.CompletedTask;
}
};
});
}
So, why is Microsoft.AspNetCore.Authentication.OpenIdConnect using HTTP when it generates the redirect_uri value of the /oauth2/authorize endpoint. Is that somethign that I need to adjust somewhere? And, does that appear to be the core issue that results in my overall https://auth.<mydomain>.com/error?error=redirect_mismatch&client_id=<myclientid> issue?
The core issue here was the reverse proxy; Kestrel running behind Apache. While I had used this setup (with certbot) regularly over the past few years, I had not previously used it with a OIDC auth scheme. The issue was the https termination at apache and the http transmission between Apache and Kestrel. An OIDC auth scheme (in my case supported by AWS Cognito) needs end-to-end https.
The "lacking https in the redirect_uri value that it creates as part of the /oauth2/authorize endpoint" was just the first of many issues I uncovered. I came up with a solution for that issue:
.AddOpenIdConnect(options =>
{
...
options.Events = new OpenIdConnectEvents
{
...
OnRedirectToIdentityProvider = async n =>
{
n.ProtocolMessage.RedirectUri = n.ProtocolMessage.RedirectUri.Replace("http://", "https://");
await Task.FromResult(0);
}
};
});
But this only solved the narrow issue of changing the redirect_uri proto; other cookie SameSite=None/Secure/http issues then appeared.
At this point, I have had success directly exposing Kestrel on 80 and 443. I realize that it's debatable whether this is a prudent idea, but it's working for me at the moment and today (Summer 2021 on .NET 5.0) it seems like Kestrel is maturing to the point where it is not one of those "only do this in development!" tools.
I found both of these articles very helpful:
https://swimburger.net/blog/dotnet/how-to-run-aspnet-core-as-a-service-on-linux
https://thecodeblogger.com/2021/05/07/certificates-and-limits-for-asp-net-core-kestrel-web-server/
Better answer. While the "Kestrel exposed to the world" answer worked, I ended up figuring out how to make the reverse proxy work with Cognito.
In the reverse proxy I ended up setting "'https' env=HTTPS" as shown here:
<VirtualHost *:*>
RequestHeader set "X-Forwarded-Proto" 'https' env=HTTPS
</VirtualHost>
I also rearanged my Prod Configure(...) as follows:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseForwardedHeaders();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseForwardedHeaders();
app.Use((ctx, next) =>
{
ctx.Request.Host = new HostString("sub.domain.com");
ctx.Request.Scheme = "https";
return next();
});
app.UseHsts();
}

SignalR .Net client cannot connect with https

I am using SignalR Core 2.4.1.0.
This is an Owin project, self-hosted.
My configuration:
public void Configuration(IAppBuilder app)
{
app.Use(async (ctx, next) =>
{
Console.WriteLine($"Incoming: {ctx.Request.Path}");
await next();
});
app.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration();
GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(10);
hubConfiguration.EnableDetailedErrors = true;
app.MapSignalR(hubConfiguration);
}
I am able to connect to https://localhost:9999/signalr/hubs from a web browser fine.
I am also able to connect to SignalR when not using https. (after removing the urlacl )
I also have tried adding a middleware before the SignalR to see the incoming request.
With http the middleware shows the Request and path.
With https the middleware shows the Request from the web browser but never shows any request from the client.
The client just changes states from connecting to disconnected with not exceptions.
My client for testing is .Net console application:
var hub = new HubConnection("https://localhost:9999");
var hubProxy = hub.CreateHubProxy("MyHUB");
hub.Error += (e) =>
{
};
hub.StateChanged += (s) =>
{
Console.WriteLine(s.NewState.ToString());
};
hub.Start();
Console.ReadLine();
I've used SignalR before but this is my first time trying to implement ssl.
In summary, .Net client will connect via http but not https.
Browser can connect to the JS library over https but I haven't tried using the JS library yet.
T.I.A.

Kestrel and https very slow

I am using Rider from JetBrains and it made me realize that configuring https directly through Kestrel makes the requests to API very slow. I have the same behaviour if I just run
dotnet MyApi.dll
When I am using Visual Studio and running the API on IIS Express I don't have any performance issues.
This is how I configured Kestrel to listen on https
X509Certificate2 cert = null;
using (var store = new X509Store(StoreName.My))
{
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindBySubjectName, "localhost", false);
cert = certs[0];
}
WebHost.CreateDefaultBuilder(args).UseKestrel(options =>
{
options.Listen(IPAddress.Loopback, 44317, listenOptions =>
{
listenOptions.UseHttps(cert);
});
})
.UseStartup<Startup>()
.Build();
I tried to remove the https and just use http, and it is working as fast as with IIS Express. So it tells me that there is something wrong with the way I am configuring https.
Is there any configuration I am missing that is making the Kestrel slower when https is activated or is it simply better to run it on IIS Express ?

Is there Any Alternative For X509Certificate2UI in ASP.net Core?

X509Certificate2Collection sel = X509Certificate2UI.SelectFromCollection(
Filteredcollection,
"Certificates",
"Select a Certificate to sign",
X509SelectionFlag.SingleSelection
);
X509Certificate2UI is giving an error at this point in asp.net core
No. X509CertificateUI is meant to pop up a selection UI on the Windows Desktop. For the web the selection process is enforced by the browser, not by any code on the server.
You must configure your web site to only accept certificates, how you do that depends on the hosting software.
For Kestrel it's in code;
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseKestrel(options =>
{
options.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps(new HttpsConnectionAdapterOptions
{
ServerCertificate = /* Your HTTPS Certificate */,
ClientCertificateMode = ClientCertificateMode.RequireCertificate,
ClientCertificateValidation = /* Validator */
});
});
})
.Build();
For IIS it's through the UI,
Select your Site in the Connections tab.
Double click the SSL Settings in the Features View window.
Check the Require SSL Check Box and select the Require radio button under Client Certificates.