Partial SSL and Authorization with Asp.Net MVC – Revisited

Back in March, I posted about creating a custom authorization filter to enable Partial SSL. While using the filter on an application I was porting to Windows Azure, I discovered a bug, which has led me to revisit my implementation. Here is the original code.

   1: public class RequireSslFilter:AuthorizeAttribute

   2: {

   3:  protected override bool AuthorizeCore(HttpContextBase httpContext)

   4:  {

   5:   if (httpContext.Request.IsLocal == false && httpContext.Request.IsSecureConnection == false)

   6:   httpContext.Response.Redirect(httpContext.Request.Url.ToString().ToLower().Replace("http", "https"));

   7:  

   8:   return base.AuthorizeCore(httpContext);

   9:  }

  10: }

 

As you can see, I’m calling base.AuthorizeCore at the end, which is what you usually do when overriding a method. However, since the purpose of he Authorize Filter is to, well authorize, the call to base.AuthorizeCore will return false if the user is not authenticated. This is a problem because you might not be authenticated at the time that this filter runs.

The reason I chose to use the Authorize Filter, is because it’s called before any other filter, as explained by Phill Haack. At first I thought about removing the call to the base.AuthorzieCore, but that seemed more like a hack, then a correct solution. Digging deeper, I discovered that the AuthorizeAttribute that I am inheriting from, implements the IAuthorizeFilter, which requires you implement the OnAuthorization method. So instead of inheriting from AuthorizeAttribute, I could just implement IAuthorizeFilter.

However, someone already did it for me. In the Asp.Net MVC futures project, released with the Asp.Net MVC RTM source, there is a RequireSSL attribute ready to use. The future’s project has more functionality then mine, allowing for the option to redirect or throw an exception. It’s nice to see I was on the right track at least.

RequireSSL Attribute from Asp.Net MVC Futures:

   1: public void OnAuthorization(AuthorizationContext filterContext) {

   2:             if (filterContext == null) {

   3:                 throw new ArgumentNullException("filterContext");

   4:             }

   5:  

   6:             if (!filterContext.HttpContext.Request.IsSecureConnection) {

   7:                 // request is not SSL-protected, so throw or redirect

   8:                 if (Redirect) {

   9:                     // form new URL

  10:                     UriBuilder builder = new UriBuilder() {

  11:                         Scheme = "https",

  12:                         Host = filterContext.HttpContext.Request.Url.Host,

  13:                         // use the RawUrl since it works with URL Rewriting

  14:                         Path = filterContext.HttpContext.Request.RawUrl

  15:                     };

  16:                     filterContext.Result = new RedirectResult(builder.ToString());

  17:                 }

  18:                 else {

  19:                     throw new HttpException((int)HttpStatusCode.Forbidden, MvcResources.RequireSslAttribute_MustUseSsl);

  20:                 }

  21:             }

  22:         }

This entry was posted in Programming (Web) and tagged . Bookmark the permalink.

2 Responses to Partial SSL and Authorization with Asp.Net MVC – Revisited

  1. Cory says:

    Thank you so much. I couldn’t find ASP.NET MVC futures source very easily though. Do you have a link?

  2. Adam says:

    The futures is included in the Asp.Net MVC source. I just downloaded the latest source from codeplex and it was under Mvc\Src\MvcFutures. Link to download: http://aspnet.codeplex.com/SourceControl/ListDownloadableCommits.aspx#DownloadLatest

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">