08 December 2016

Forcing an ASP.NET MVC site to only serve HTTPS


Forcing an ASP.NET MVC site to only serve HTTPS


Why force HTTPS?

Hyper Text Transfer Protocol Secure (HTTPS) is the secure version of HTTP, the protocol over which data is sent between your browser and the website that you are connected to. The 'S' at the end of HTTPS stands for 'Secure'. It means all communications between your browser and the website are encrypted.



How to force HTTPS


ASP.NET Action Filters

ASP.NET MVC allows you to apply a [RequireHttps] attribute on individual page controllers. It also allows the attribute to be applied globally by adding code to Application_Start in the Global.asax.


The problem with the built-in RequireHttpsAttribute

In a nutshell, the problem is that it returns 302, a temporary redirection HTTP Status Code (see List of HTTP Status Codes [Wikipedia]). This is an SEO problem. A return value of 301 means "Moved Permanently" and is a hint to the search engines to update their indexes.

If the built-in attribute is used, a result similar to the one below is obtained when the page is retrieved:


curl http://www.localexample.com:4433/ -iILk
HTTP/1.0 302 Found

The desired result is:


curl http://www.localexample.com:4433/ -iILk
HTTP/1.0 301 Moved Permanently



Writing your own version of the RequireHttpsAttribute

Writing your own attribute is fairly straight-forward.

  1. Create a class that inherits from the RequireHttpsAttribute class
  2. Override the HandleNotHttpsRequest method.
  3. Add some code to handle running in your local development environment. (NB you will need to create a self-signed certificate for a dummy domain (we use www.localexample.com), install it on your machine and update your hosts file).
  4. Build the HTTPS address
  5. End the method by setting the Result property of the filterContext to a new RedirectResult that uses the HTTPS address and sets the permanent parameter to true.

Although you can apply this attribute to your controller methods individually, applying it globally minimizes the effort and ensures that nothing is missed.


Wiring up your filter configuration

You will need to create/update the FilterConfig class.

The code shown below illustrates the necessary change, which is simply the addition of your custom attribute to the global filter collection.


Code is then added to the App_Start method in the Global class to run RegisterGlobalFilters.

The code below illustrates how to do this.






No comments: