Introduction
When we, as developers, encounter the same coding scenario time and time again, we naturally tend to encapsulate the coding logic and reuse it in an effort to save time and minimize maintenance.
Recently, while developing a website called Bigshot Hotshot, I reevaluated the need to switch between secure (HTTPS/SSL) and non-secure (HTTP/non-SSL) pages. I noticed that while coding, we do not, in most cases, think about using SSL. One reason is that (at the time of this writing) the ASP.NET Development Server does not support SSL. To test SSL pages, we need to add our application/website to IIS and configure it accordingly. Another problem I wanted to solve was how to hint to IIS that certain pages should always use HTTPS while others should always use HTTP. To complicate things even further, I wanted to take SEO (search engine optimization) into account as well so that redirecting between secure and non-secure pages does not have a negative impact on the website's SEO.
This article presents one way of solving the aforementioned issues. For brevity, we will abbreviate the phrase: switch(ing) between HTTP and HTTPS to HTTP <=> HTTPS.
Background Research
Solution/Proposal 1
While researching potential solutions for the issue of HTTP <=> HTTPS, I came across an article by Matt Sollars: Switching Between HTTP and HTTPS Automatically: Version 2. It is a well-written solution to the above problem. I like how you can enforce entire directories to use SSL, as well as individual pages. I also like the web.config based approach to specify which files should use SSL. On the other hand, the solution is more complicated than what I needed. In addition, HTTP <=> HTTPS by calling Response.Redirect([path], true), and ending the Response is not very SEO friendly.
Solution/Proposal 2
Another solution to HTTP <=> HTTPS I came across was by Yohan B: RequireSSL Attribute for ASP.NET. I like the Attribute based approach of specifying that certain pages are required to use SSL. I also like the use of the #if DEBUG directive to tell the compiler not to HTTP <=> HTTPS while running in Debug mode (since ASP.NET Development Server does not support SSL anyway). What I am not quite fond of, however, is the use of a base Page that all other Pages inherit from to call the Validate() method and control HTTP <=> HTTPS. Also, just like in the above article, HTTP <=> HTTPS by calling Response.Redirect([path], true), and ending the Response is not very SEO friendly.
Our Strategy
What we will be looking at in the next section is another way to HTTP <=> HTTPS. We will use Attributes to mark which Pages require SSL, and we will implement a custom HTTP module responsible for intercepting requests to our ASPX pages and for HTTP <=> HTTPS when necessary. We will also examine how to do this in an SEO friendly manner.
The Code
First off, we need to define an Attribute so we can decorate the Pages that require SSL with that Attribute. Let's define an Attribute called RequireSSL:
/// <summary>
/// Attribute decorated on classes that use SSL
/// <summary>
[AttributeUsage(AttributeTargets.Class)]
sealed public class RequireSSL : Attribute
{
}
In our example project, the login.aspx and signup.aspx pages require SSL. We will mark them accordingly (notice the RequireSSL attribute):
/// <summary>
/// The Login Page
/// </summary>
[RequireSSL]
public partial class login : System.Web.UI.Page
{
...
}
/// <summary>
/// The SignUp Page
/// </summary>
[RequireSSL]
public partial class signup : System.Web.UI.Page
{
...
}
Next, we will implement our custom HTTP module. It will be configured so that the code for HTTP <=> HTTPS only runs when compiled in Release mode:
/// <summary>
/// HttpModule for switching between HTTP and HTTPS (HTTP <=> HTTPS)
/// </summary>
public class RequireSSLModule : IHttpModule
{
public void Init(HttpApplication context)
{
// only attach the event if the build is not set to Debug
#if !DEBUG
// The PreRequestHandlerExecute event occurs just
// before ASP.NET begins executing a handler such as a Page
// In here we can acquire a reference
// to the currently executing ASPX Page
context.PreRequestHandlerExecute +=
new EventHandler(OnPreRequestHandlerExecute);
#endif
}
...
}
Let's take a closer look at the PreRequestHandlerExecute event.
/// <summary>
/// Handle switching between HTTP and HTTPS.
/// It only switches the scheme when necessary.
/// Note: By scheme we mean HTTP scheme or HTTPS scheme.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
// obtain a reference to the ASPX Page
System.Web.UI.Page Page =
HttpContext.Current.Handler as System.Web.UI.Page;
Read more: Codeproject
0 comments:
Post a Comment