What is the difference between app.UseHsts() and app.UseExceptionHandler()? - c#

On the Startup.cs file of an .NET Core app, by default it make use of
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
But in some cases I can find the use of
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler();
}
What is the difference?

Hsts is a security feature to force SSL. It has nothing to do with exceptions.
UseHsts
UseExceptionHandler

It is an old question but if you still didn't figure out the answer then this might help.
UseHsts adds a header Strict-Transport-Security to the response. When the site was accessed using HTTPS then the browser notes it down and future request using HTTP will be redirected to HTTPS. So, accessing the site using HTTPS at least once is mandatory to make this work.
Also the expiration time set by the Strict-Transport-Security header elapses, the next attempt to load the site via HTTP won't be automatically redirected to HTTPS.

Here is additional info about UseHsts,
HSTS is a client side performance optimization to avoid an extra request to the server for more info read Ramesh's answer. but is has some limitations:
It is not guaranteed to limit traffic to HTTPS only.
It requires at least 1 successful HTTPS request.
It depends on client support, client may or may not support HSTS.
About UseExceptionHandler, you can use this middleware to catch unhandled exceptions globally.

You should be aware that you won't notice this header when you run against localhost, because the HSTS middleware ignores requests to 127.0.0.1 and local host.
Also this header is also only sent over HTTPS
See the source code here:

Related

ASP.NET Core 5.0 - Redirecting non-WWW to WWW in Azure

I have an ASP.NET Core 5.0 app and I've tried to use very simple code inside Startup.cs to be sure that all requests without www would be redirected to www domain (and http to https).
I've specified my domain to avoid the situation that the rule applies also to myapp.azurewebsites.net as the app is hosted in Azure (without the domain list I was getting www.myapp.azurewebsites.net). While URL http://www.example.com/Test is properly redirected to https://www.example.com/Test, for https://example.com/Test nothing happens - I get error 404 Not found. I'll appreciate any suggestions.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
string[] domains = { "example.com" };
app.UseRewriter(new RewriteOptions().AddRedirectToHttpsPermanent().AddRedirectToWwwPermanent(domains));
app.UseHsts();
app.UseHttpsRedirection();
(...)
}
I've found few similar questions, but they were for pre-3.0 Core and the logic of AddRedirectToWwwPermanent changed in 3.0. Maybe it'd be better to do it in web.config, but I saw some information that it's recommended to use Rewrite middleware for Core apps... Or maybe as it's hosted on Azure (Windows) I should explore option .AddIISUrlRewrite(iisUrlRewriteStreamReader)?
Side question: not sure if I should keep all three https redirections "rules": .AddRedirectToHttpsPermanent(); app.UseHsts(); app.UseHttpsRedirection(). They seem a bit overlapping, but not sure which to keep (or it's fine to have all three together).

HTTPS redirect using Azure Storage Emulator

I'm working on a local ASP.NET web application written in C# and hosted using IIS Express.
I want to store a blob using Azure Storage Emulator with the default configuration. This is my Connection String:
DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;
When I ran my local web-app and I tried to store a blob, I got this error in Chrome:
PUT https://127.0.0.1:10000/devstoreaccount1/test1/0001_44f8f0366bcd492596c2d0ca76ae4329?sv=2018-03-28&sr=c&sig=XvGrFIEJzVi259336q56WKRMlJOJ8yYtq7QzaA%2FqByM%3D&se=2020-02-04T17%3A44%3A07Z&sp=w&api-version=2018-03-28 net::ERR_SSL_PROTOCOL_ERROR
Since the url in this error has the https protocol, I commented the UseHttpsRedirection policy in Startup.cs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.SetBasePath(env.ContentRootPath);
configurationBuilder.AddJsonFile("appsettings.json", false, true);
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
configurationBuilder.AddUserSecrets<Startup>();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes => { routes.MapRoute(name: "default", template: "{controller=Site}/{action=Index}"); });
}
Anyway, nothing changed after that. Anyone know why I have an https redirect even if I'm using DefaultEndpointsProtocol=http?
The storage emulator supports connection via HTTP only. However, HTTPS is the recommended protocol for accessing resources in a production Azure storage account.
Now, often this error disappears itself when you refresh the page, but sometimes it comes again and again. If you are experiencing such kind of warnings, here we’re explaining various solutions to fix ERR_SSL_PROTOCOL_ERROR or you could change other browser to try again.
1.Check the Date of Your System
2. Clear Browsing Data
3. Clear Your SSL State
4. Disable QUIC Protocol of Chrome
5. Check Your Antivirus Settings
6. Check Your Firewall
7. Disable Extensions
8. Adjust Your Internet Security and Privacy Level

Request.IsHttps and Request.Scheme are showing that request is HTTP instead of HTTPS

I'm working with an .Net Core web app and I need to verify the request is HTTPS. I have installed a certificate in Azure with Let's encrypt and I have a cloudflare CDN but always shows me as if the request was not HTTPS.
I've used
this.Request.Scheme.Equals("https")
and
this.Request.IsHttps
Do you have any idea what's happenning?
The Cloudflare CDN, although it serves your requests as HTTPS, is actually making the request to your website as HTTP.
You are likely using Cloudflare's Flexible mode. You likely want to use one of the Full modes.
This usually happens when your CDN (Cloudflare) is sending requests to your web server over HTTP.
You can either instruct Cloudflare to only use HTTPS, or enforce this locally via ASP.NET.
If Kestrel is exposed to the internet directly, then you can actually instruct Kestrel to redirect requests from HTTP to HTTPS.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts(); // <=== Add this =====
}
app.UseHttpsRedirection(); // <=== Add this =====
}

How to access an API from the same hostname with Angular 4 frontend and DotNet Core backend?

I have an Angular 4 frontend using a .NET Core-backend in the same solution.
As far as I can tell you can't access the window object from Angular the same way, so there's no good way to decode get the current location/environment.
With a .NET Core-backend I also don't have an angular.cli.json file so that I can configure an environments/environment.prod.ts environments/environment.local.ts kind of setup.
What I'm wondering is why I can't access say my backend API without specificing the hostname (which I have trouble accessing) without entering it specifically?
On a localhost it's: http://localhost:port/api// for example but I have to specify http://localhost:port when I want to be able to access it with '/api//' directly.
So when working locally I have one environment and deployed another one. So I can't exactly deploy it with localhost URL.
What is the proper way for Angular's HTTP client to use the same hostname in requests?
I have set up environments like I said, but during release build it does not choose the environment.prod.ts file for example. I guess this has to do with the .NET Core solution rather than Angular.
Any suggestions?
Either by a configuration setup for production/development/local or to get the environmental settings working in a .NET Core solution with Angular 4.
You must change the Startup.cs. AnyWay, if you use Visual Studio 2017 you can use the angular template
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true
});
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseDefaultFiles();
app.UseStaticFiles();
app.Use(async (context, next) =>
{
if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value) && !context.Request.Path.Value.StartsWith("api"))
{
context.Request.Path = "/Index.cshtml";
context.Response.StatusCode = 200;
await next();
}
});
}
So, a http call can be like
this._http.get('/api/controller/action')

AddRedirectToHttps() doesn't redirect to Https

The Enforcing SSL in a ASP.NET Core App guide on MSDN, tells me to add the following code to my Configure method in the Startup class, in order to redirect all http request to https:
var options = new RewriteOptions()
.AddRedirectToHttps();
app.UseRewriter(options);
Having added the code in the correct place, and testing a http request in debug mode, I get a connection reset error in chrome:
This site can’t be reached
The connection was reset.
Try:
Checking the connection
Checking the proxy and the firewall
Running Windows Network Diagnostics
ERR_CONNECTION_RESET
I'm trying to access the same URL (including port.. which I think is where I might be going wrong?) that I would if I was using https... I.E, I'm typing http://localhost:44376 instead of https://localhost:44376 into my address bar.
A slimmed down version of my Configuration method looks like this:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
var options = new RewriteOptions()
.AddRedirectToHttps();
app.UseRewriter(options);
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseIdentity();
app.UseFacebookAuthentication(new FacebookOptions()
{
AppId = Configuration["Authentication_FacebookAppId"],
AppSecret = Configuration["Authentication_FacebookAppSecret"]
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
As this github post confirms, I was on the right lines thinking it was probably the port that was causing the issue. (Essentially, you can't listen for http and https requests on the same port.)
The fix for me was actually three-fold:
Firstly, you need to be careful how your running your app in development. When running visual studio on windows, the default is to startup using IIS / IIS Express. This causes a problem because it uses the application url defined in the project settings, rather than the urls we try to pass to kestrel via the startup class. (It's the applicationUrl defined in the iisSettings section of launchSettings.json)
If you expand the drop down on the start button inside Visual Studio, you should see an option with your project name, this starts your application using Kestrel via the dotnet CLI.
Secondly, you need to define two url's for kestrel to listen on, one for http and the other for https. This is done by simply passing in two url's, with different ports to the UseUrls() method in main():
var host = new WebHostBuilder()
.UseKestrel(options => {
options.UseHttps(certFile, certPass);
})
.UseContentRoot(Directory.GetCurrentDirectory())
.UseUrls("https://*:44388", "http://*:8080")
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
Finally, if your not using the default https port (443), you'll need to specify which port you want kestrel to redirect http request too. To do this, simply overload the AddRedirectToHttps() method, by passing in a status code and the port your wanting to redirect too. I've used the status code 301 to permanently redirect to https.
var options = new RewriteOptions()
.AddRedirectToHttps(301, 44388);
I had the similar issue with the usage of .AddRedirectToHttps(). But I found out that it might not set the port correctly to the default SSL port 443.
Use AddRedirectToHttpsPermanent() instead!, because it will default the port to 443.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Redirects all HTTP requests to HTTPS
if (env.IsProduction())
{
app.UseRewriter(new RewriteOptions()
.AddRedirectToHttpsPermanent());
}
....
}

Categories