Switching to Https and back to Http in ASP.NET MVC

Within ASP.Net MVC, there is a handy RequireHttpsAttribute that you can use to automatically direct an incoming action request to go through HTTPS.  Typically this would be used for a login or checkout process:

[RequireHttps]
public Actionresult LogIn()
{
...
}

Unfortunately, once switched over to HTTPS, all subsequent requests will also be sent via HTTPS as there is no build in mechanism to return the user to HTTP.

In order to resolve this, I have written a new version of the RequireHttpsAttribute that switches the user back to Http when required.

public class RequireHttpsAttribute : System.Web.Mvc.RequireHttpsAttribute
{
   public bool RequireSecure = false;
   public override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext)
   {
       if (RequireSecure)
       {
         // default RequireHttps functionality
         base.OnAuthorization(filterContext);
       }
       else
       {
         // non secure requested
         if (filterContext.HttpContext.Request.IsSecureConnection)
         {
             HandleNonHttpRequest(filterContext);
         }
       }
    }

   protected virtual void HandleNonHttpRequest(AuthorizationContext filterContext)
   {
      if (String.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
      {
         // redirect to HTTP version of page
         string url = "http://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl;
         filterContext.Result = new RedirectResult(url);
      }
   }
}

This action filter inherits from the standard RequireHttpsAttribute and overrides the OnAuthorization method.  It also has a parameter ‘RequireSecure’ that is set when applying the filter to indicate whether it should switch to secure (HTTPS) or not.

In order to switch to HTTPS, we then use

[RequireHttps(RequireSecure = True)]
public Actionresult LogIn()
{
...
}

And then set Secure = False either on actions that require it, or at the controller level, or in my case I set it on my base controller class so that it is applied to every action that has not been specifically decorated set to be via HTTPS.

[ActionFilters.RequireHttps(RequireSecure = false)]
public abstract class ControllerBase : Controller
{
...
}

tim has written 12 articles

4 thoughts on “Switching to Https and back to Http in ASP.NET MVC

  1. Roman says:

    Hey,
    i want to first thank you for your article. It got me started on action filters as I am a bit new to the framework.
    I did have a quick question. Is there a reason why you do not use a property RequireSecure parameter instead of public variable. I have been generally taught to consider that as a bad C# practice.

    1. tim says:

      Under normal circumstances you are correct, public properties are generally not best practice. I believe, however, that the technique I used here was necessary because of the way Attribute functions work. I must say I’m not absolutely certain, I believe I copied the pattern used in the MVC source code.

  2. rapozao says:

    Hey,

    thank you for article, but I already have doubts, maybe because I’m new in .net mvc.

    I have some actions that should be call in http and https protocols.

    Does this code do this? I mean, if I use [RequireHttps(RequireSecure = True)] it means that this action could be http and https?

    If I use [RequireHttps(RequireSecure = False)] it is aways https?

Comments are closed.