Redirect from Http to Https in ASP.NET

5. January 2010

There are a few ways to redirect from http to https in asp.net, but I wanted a somewhat simple and efficient method.  After researching a bit, I could add some code to global.asax, or make my own custom configuration section in the web.config.  Well I chose to do a little variation of a "custom" section in the web.config.  I don't end up creating a class that inherits from ConfigurationSection, but just a few other things.  To create a custom configuration section, here are a few links you may want to look at:

http://www.4guysfromrolla.com/articles/032807-1.aspx
http://msdn.microsoft.com/en-us/library/2tw134k3%28VS.80%29.aspx

 

Now, here is what I did:

  • Add a section in the web.config called <SecurePages>, that mimics the <appSettings> section
  • Create a class file SecurePages.cs with two classes in it.
  • Add some code to Global.asax

 

Lets start with what we need to add the the web.config.  First, you need to add the following under the <configSectionsGroup>.  If you already have code in this section, make sure you don't add it under an existing <sectionGroup>

A few notes here. 1) notice the name attribute and the value called "SecurePages". This is what we are going to call our section (you'll see in a bit), and 2) notice how it is of type System.Configuration.NameValueFileSectionHandler.  This is what allows us to mimic the key/value format within our section, like the <appSettings>

The last thing we need to add to our web.config is the new section <SecurePages> with pages and directories we would like secure:

A few notes here. 1) you'll see for the key value we are either putting a directory, or putting a web page name. 2) the value is either "directory" or "page".  If the value is "directory" then all requests made to items within that directory are switched to https://. Obviously, if the value is "page" then requests for that page will be switched to https://

Now on to Step 2. Creating a class file called SecurePages.cs with a class named SecurePage and a class named SecurePath in it. Both of these classes will belong in the same file.

The first class we are making in the file is SecurePage with two properties called Path and PathType. Code is below:

The second class we are making reads the values out of the web.config in our section <SecurePages> and stores them in a List<> of type SecurePage. Then sees if the incoming request is in that list to make a switch to https://.  Code for this is below:

The final step in the process is to add the code in the global.asax in the Application_BeginRequest method to see if the request coming in should be switched to https:// You'll notice we are calling the static method IsSecure in the class SecurePath from what we created above. You'll also notice the path we are passing in is the AbsolutePath (i.e., /WebForm1.aspx) since that is the type of URL we put in the web.config earlier.

I know this may seem like a lot of trouble to redirect a request from http to https, but once setup it's easy to manage in the web.config.  Being able to manage it here allows you not to worry about recompiling the application each time you need to make a change.  Also, I know you can do this sort of thing in IIS 7, but this allows a different way of controling it.  This may not be the best method for large scale enterprise apps, but when dealing with shared hosting companies (i.e., Go Daddy) you never know how much control you'll get over IIS. 

One improvement that can be made to this code is to add this list to the Cache or Session that way it doesn't have to read the web.config on every request.

However, I left that out of this example so that you can modify as needed and not worry about anything else I have put in there.

Either way, questions or comments on how to improve this I would enjoy hearing about.  Good luck!

 

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

ASP.NET

Comments

Brian Dishaw
2/14/2010 9:06:52 PM #
This is great!

I love being able to configure it via the web.config as well.

Thanks so much!
2/15/2010 1:47:09 AM #
No problem Brian. Glad it could help you out.  I have found this to be working out quite well.
2/17/2010 6:50:14 AM #
great article, i want to use it on my current project.
2/17/2010 10:02:01 AM #
Pingback from ramanisandeep.wordpress.com

Redirect from Http to Https in ASP.NET « Ramani Sandeep's Blog
2/17/2010 2:34:47 PM #
Good article John.  As you said this kind of redirect can be handled a few ways either through IIS or .NET but having control like this in the web.config is really the way to go.  After you hand off the app to a client, they are going to need an easy way to specify pages or directories that require SSL, and this is really flexible way to do it.

Good work!
2/17/2010 10:56:38 PM #
Redirect from Http to Https in ASP.NET
www.xdevsoftware.com/.../Redirect-from-Http-to-Https-in-ASPNET.aspx" rel="nofollow">www.xdevsoftware.com/.../...o-Https-in-ASPNET.aspx

Redirect from Http to Https in ASP.NET www.xdevsoftware.com/.../Redirect-from-Http-to-Https
Web Guy
2/17/2010 11:36:09 PM #
There's a decent article that fully explains how to do this exact thing on CodeProject. I've even heard there is a full-blown OSS project coming out of it that will work for several different scenarios, including via ASP.NET MVC.

www.codeproject.com/.../WebPageSecurity_v2.aspx
2/18/2010 4:18:59 AM #
This looked familiar and then I remember using it recently on a site that I worked on.

www.codeproject.com/.../WebPageSecurity_v2.aspx

Works very similar to way you blog post mentioned, and works like a charm for my purposes.
2/18/2010 7:58:29 AM #
@Web Guy, @Irishmaninus thanks for the info. I checked out that article and it is similiar. glad to know I wasn't the only one thinking like this Smile
stefan
2/18/2010 10:49:49 AM #
Why in the web.config you don't use something like the example from the links instead of key/value pair? For example:

<ScottsSettings
     quoteOfTheDay="Hello, World!"
     yourAge="28">
   <favoriteStates>
      <add name="California" abbreviation="CA" />
      <add name="Missouri" abbreviation="MO" />
      <add name="Illinois" />
   </favoriteStates>
</ScottsSettings>
Ras Fred
2/18/2010 2:45:07 PM #
Nice implementation.  I did similar SSL redirect but in a different way:
- Add a "_useSSL" variable with a public setter to an ancestor Page class.  
- Add code to the ancestor Page to check the var & redirect if necessary(like your code above).
- Add an attribute to the @Page tag for the aspx
<%@Page [...] UseSSL="always">

it requires an ancestor web page class, but it is very easy/quick to implement, flexible, and works well for page designers.
2/18/2010 4:47:43 PM #
@stefan I didn't want to do something like that because then I would have to make my own class to read the custom config section, which would have required more code.  I like their approach from the links in my blog, but didn't want to go that route when I could utilize the key/value pair already available.
2/18/2010 4:49:22 PM #
@Ras Fred. Good idea and way of going about it. I'll have to keep that in mind  
2/18/2010 5:07:03 PM #
Pingback from alvinashcraft.com

Dew Dump – February 17, 2010 | Alvin Ashcraft's Morning Dew
2/18/2010 7:49:22 PM #
Social comments and analytics for this post

This post was mentioned on Twitter by johnmendez00: new blog post: http://is.gd/5MV6t another way to redirect http to https
stefan
2/18/2010 9:28:46 PM #
You are right about the extra code, but i think that the section will be more beatiful than key/value and the logic of the method IsSecure will be more simple, because it will be done in the extra class. But that is my opinion, great post.
2/19/2010 8:44:44 PM #
Hello,

Contains is a case sensitive comparison. If we have insert

&lt;add key="/admin" value="directory" /> and someone navigate to http://yourdomain/Admin , isSecure will return false.

if (path.Contains(page.Path))
{
  isSecure = true;
}

Thanks,
Bryian Tan
2/19/2010 11:08:07 PM #
@Bryian Tan, Thanks for that catch. I will update the code accordingly to incorporate the ToLower(). So it will look something like

path.ToLower().Contains(page.Path.ToLower())
2/21/2010 8:31:37 AM #
Great, quite useful!
Chris T
3/5/2010 5:51:09 PM #
Perhaps I'm missing something and you can point out what it is...

Are you using a BasePage in your .Net site? If not, I think you'd be surprised how useful they are. If you are, it seems to me that'd be a much better place to handle forcing a secure connection (or anything else, for that matter).

Just create a property (i.e. - .RequireSSL) in the BasePage available to the page which can be set in the page's PreInit event of the life cycle.  Then in your BasePage's overriding of the OnInit event, check if the property has been set. If so, check if Request.IsSecureConnection. If it's not secure, redirect to the correct protocol.

This is how we handle it at my 9-to-5'er and if we want a new page to be secure, we don't have to remember to add a new item to the List(of T) every time. We just set the property at the page level, such as:

Me.RequireSSL = True

As you said - your implementation either has to read the config section each time or store it in the cache/session (in this case, you would NOT use Sessions as there'd be a new List(of T) for each active session, definitely not the most efficient use of memory).

With an exposed property on the page, you just set it and forget it.  No mucking around with additional files.

[SAMPLE]
=========================
' In base page:
Private _RequireSSL As Boolean = False
Public Property RequireSSL() As Boolean
  Get
    Return _RequireSSL
  End Get
  Set(ByVal value As Boolean)
    _RequireSSL = value
  End Set
End Property



Private Sub PushSSL()
  Dim SECURE As String = "https://"
  Dim UNSECURE As String = "http://"
  If Request.IsSecureConnection = False Then
    UrlProtocol = UNSECURE
  ElseIf Request.IsSecureConnection = True Then
    _UrlProtocol = SECURE
  End If
  'Force required into secuire channel
  If RequireSSL = True And Request.IsSecureConnection = False Then
    Dim URLString As String = Right(Request.Url.ToString, Request.Url.ToString.Length - 7)
    Response.Redirect(SECURE & URLString)
  End If
  ' We had some code to kick them out of secure if they were
  ' needlessly on https, but older browsers squawk when done
  ' automagically
End Sub



Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
  MyBase.OnInit(e)
  ' See if this page should be secured
  PushSSL()
End Sub
=========================




=========================
' In any new page you create:
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
  Me.RequireSSL = True
End Sub
=========================
[/SAMPLE]


I think this might be what Ras Fred is talking about, but I'm not sure what an ancestor page class is.

Hope this helps.
3/5/2010 8:03:33 PM #
@Chris T, Nah you're not missing anything, I like the way you mentioned as well. I Appreciate such a detailed comment as I'm sure it will help others who read this too.  Great feedback has been provided regarding this post. I love everyone throwing their ideas in...it's the only way we get better right?! Smile  
3/5/2010 11:03:48 PM #
links for 2010-03-05

links for 2010-03-05

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading