Tutorial :SSL pages under ASP.NET MVC



Question:

How do I go about using HTTPS for some of the pages in my ASP.NET MVC based site?

Steve Sanderson has a pretty good tutorial on how to do this in a DRY way on Preview 4 at:

http://blog.codeville.net/2008/08/05/adding-httpsssl-support-to-aspnet-mvc-routing/

Is there a better / updated way with Preview 5?,


Solution:1

If you are using ASP.NET MVC 2 Preview 2 or higher, you can now simply use:

[RequireHttps]  public ActionResult Login()  {     return View();  }  

Though, the order parameter is worth noting, as mentioned here.


Solution:2

MVCFutures has a 'RequireSSL' attribute.

(thanks Adam for pointing that out in your updated blogpost)

Just apply it to your action method, with 'Redirect=true' if you want an http:// request to automatically become https:// :

    [RequireSsl(Redirect = true)]  

See also: ASP.NET MVC RequireHttps in Production Only


Solution:3

As Amadiere wrote, [RequireHttps] works great in MVC 2 for entering HTTPS. But if you only want to use HTTPS for some pages as you said, MVC 2 doesn't give you any love - once it switches a user to HTTPS they're stuck there until you manually redirect them.

The approach I used is to use another custom attribute, [ExitHttpsIfNotRequired]. When attached to a controller or action this will redirect to HTTP if:

  1. The request was HTTPS
  2. The [RequireHttps] attribute wasn't applied to the action (or controller)
  3. The request was a GET (redirecting a POST would lead to all sorts of trouble).

It's a bit too big to post here, but you can see the code here plus some additional details.


Solution:4

Here's a recent post from Dan Wahlin on this:

http://weblogs.asp.net/dwahlin/archive/2009/08/25/requiring-ssl-for-asp-net-mvc-controllers.aspx

He uses an ActionFilter Attribute.


Solution:5

Some ActionLink extensions: http://www.squaredroot.com/post/2008/06/11/MVC-and-SSL.aspx Or an controller action attribute that redirects to https:// http://forums.asp.net/p/1260198/2358380.aspx#2358380


Solution:6

For those who are not a fan of attribute-oriented development approaches, here is a piece of code that could help:

public static readonly string[] SecurePages = new[] { "login", "join" };  protected void Application_AuthorizeRequest(object sender, EventArgs e)  {      var pageName = RequestHelper.GetPageNameOrDefault();      if (!HttpContext.Current.Request.IsSecureConnection          && (HttpContext.Current.Request.IsAuthenticated || SecurePages.Contains(pageName)))      {          Response.Redirect("https://" + Request.ServerVariables["HTTP_HOST"] + HttpContext.Current.Request.RawUrl);      }      if (HttpContext.Current.Request.IsSecureConnection          && !HttpContext.Current.Request.IsAuthenticated          && !SecurePages.Contains(pageName))      {          Response.Redirect("http://" + Request.ServerVariables["HTTP_HOST"] + HttpContext.Current.Request.RawUrl);      }  }  

There are several reasons to avoid attributes and one of them is if you want to look at the list of all secured pages you will have to jump over all controllers in solution.


Solution:7

I went accross this question and hope my solution can helps someone.

We got few problems: - We need to secure specific actions, for instance "LogOn" in "Account". We can use the build in RequireHttps attribute, which is great - but it'll redirect us back with https://. - We should make our links, forms and such "SSL aware".

Generally, my solution allows to specify routes that will use absolute url, in addition to the ability to specify the protocol. You can use this approch to specify the "https" protocol.

So, firstly I've created an ConnectionProtocol enum:

/// <summary>  /// Enum representing the available secure connection requirements  /// </summary>  public enum ConnectionProtocol  {      /// <summary>      /// No secure connection requirement      /// </summary>      Ignore,        /// <summary>      /// No secure connection should be used, use standard http request.      /// </summary>      Http,        /// <summary>      /// The connection should be secured using SSL (https protocol).      /// </summary>      Https  }  

Now, I've created hand-rolled version of RequireSsl. I've modified the original RequireSsl source code to allow redirection back to http:// urls. In addition, I've put a field that allows us to determine if we should require SSL or not (I'm using it with the DEBUG pre-processor).

/* Note:   * This is hand-rolled version of the original System.Web.Mvc.RequireHttpsAttribute.   * This version contains three improvements:   * - Allows to redirect back into http:// addresses, based on the <see cref="SecureConnectionRequirement" /> Requirement property.   * - Allows to turn the protocol scheme redirection off based on given condition.   * - Using Request.IsCurrentConnectionSecured() extension method, which contains fix for load-balanced servers.   */  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]  public sealed class RequireHttpsAttribute : FilterAttribute, IAuthorizationFilter  {      public RequireHttpsAttribute()      {          Protocol = ConnectionProtocol.Ignore;      }        /// <summary>      /// Gets or sets the secure connection required protocol scheme level      /// </summary>      public ConnectionProtocol Protocol { get; set; }        /// <summary>      /// Gets the value that indicates if secure connections are been allowed      /// </summary>      public bool SecureConnectionsAllowed      {          get          {  #if DEBUG              return false;  #else              return true;  





        
Previous
Next Post »