Scott Cate Weblog 

scott.cate@myKB.com
http://scottcate.myKB.com



Scott Cate KB > ASP.NET Code Samples - Findings Start Over
Search the Knowledge Base
 
Start Search in the Following Category
Date Modified
Wednesday, April 28, 2004
HttpModule that acts as a SSL Switcher

If you're working with SSL and ASP.NET, you know it's a challenge to be able to know when to switch back and forth between HTTP and HTTPS calls.

I've thrown together a little HttpModule that inpects requests, and matches them to settings in web.config custom sections. There are files and paths sections. There are a ton of ways to do this, but I wanted a way to add this to projects that are already in existence, and an HttpModule seems to be the best bet.

Basically you can add this to your project in 2 easy steps.

  1. Copy DLL into /Bin
  2. Add Settings into web.config file.

Here is the sample web.config settings to wire up the module, and the custom sections data.


1:     <configuration>

2: <configSections>
3: <sectionGroup name="RequiresSSL">
4: <section name="RequiresSSL_Files" type="System.Configuration.NameValueSectionHandler,system,Version=1.0.3300.0,Culture=neutral, PublicKeyToken=b77a5c561934e089,Custom=null" />
5: <section name="RequiresSSL_Paths" type="System.Configuration.NameValueSectionHandler,system,Version=1.0.3300.0,Culture=neutral, PublicKeyToken=b77a5c561934e089,Custom=null" />
6: </sectionGroup>
7: </configSections>
8:
9:
10: <RequiresSSL>
11: <RequiresSSL_Files>
12: <add key="login.aspx" value="true" />
13: <add key="WebForm1.aspx" value="true" />
14: </RequiresSSL_Files>
15: <RequiresSSL_Paths>
16: <add key="/Secure" value="true" />
17: </RequiresSSL_Paths>
18: </RequiresSSL>
19:
20:
21: <system.web>
22: <httpModules>
23: <add type="HttpSslSwitcher.SslSwitcher, HttpSslSwitcher" name="SslSwitcher" />
24: </httpModules>
25: </system.web>
26: </configuration>
27:

and Here is the class code for the module.


1:     using System;

2: using System.Web;
3: using System.Collections;
4: using System.Configuration;
5: using System.Collections.Specialized;
6:
7: namespace HttpSslSwitcher
8: {
9: /// <summary>
10: /// Summary description for SslSwitcher.
11: /// </summary>
12: public class SslSwitcher : IHttpModule
13: {
14: public SslSwitcher()
15: {
16: //
17: // TODO: Add constructor logic here
18: //
19: }
20: #region IHttpModule Members
21:
22: public void Init(HttpApplication context)
23: {
24: context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
25: }
26:
27: public void Dispose()
28: {
29: // Nothing To Do
30: }
31: #endregion
32:
33: private void context_PreRequestHandlerExecute(object sender, EventArgs e)
34: {
35: HttpApplication myApp = (HttpApplication)sender;
36: HttpContext ctx = HttpContext.Current;
37:
38: //Get list of files to be secured
39: NameValueCollection sslFiles = (NameValueCollection)
40: ConfigurationSettings.GetConfig("RequiresSSL/RequiresSSL_Files");
41:
42: //Get list of paths to be secured
43: NameValueCollection sslPaths = (NameValueCollection)
44: ConfigurationSettings.GetConfig("RequiresSSL/RequiresSSL_Paths");
45:
46: bool RequiresSSL = false;
47:
48: //Simple Screen Writes to let the user know what's going on, what we found
49: WriteEntriesToResponse(sslFiles,"Files",ctx);
50: WriteEntriesToResponse(sslPaths,"Paths",ctx);
51:
52: string Host = ctx.Request.Url.Host.ToString();
53: string File = ctx.Request.Url.PathAndQuery.ToLower();
54:
55: //Strip queary string for now
56: if(File.IndexOf("?") > -1)
57: File = File.Substring(0,File.IndexOf("?"));
58:
59: //First check the paths
60: RequiresSSL = IsFileInrequiredCollection(sslPaths, ctx, File);
61:
62: //Now check the files, only if path doesn't require SSL
63: if(RequiresSSL == false)
64: RequiresSSL = IsFileInrequiredCollection(sslFiles, ctx, File);
65:
66: if(RequiresSSL && ctx.Request.IsSecureConnection == false)
67: ctx.Response.Redirect(ctx.Request.Url.ToString().ToLower().Replace("http:","https:"));
68: if(RequiresSSL == false && ctx.Request.IsSecureConnection)
69: ctx.Response.Redirect(ctx.Request.Url.ToString().ToLower().Replace("https:","http:"));
70: }
71:
72:
73: private bool IsFileInrequiredCollection(NameValueCollection nv, HttpContext ctx, string filename)
74: {
75: bool RequiresSSL = false;
76: foreach(string key in nv.Keys)
77: {
78: if(filename.StartsWith(key.ToLower()) || filename.EndsWith(key.ToLower()))
79: {
80: RequiresSSL = true;
81: break;
82: }
83: }
84: return RequiresSSL;
85: }
86:
87: private void WriteEntriesToResponse(NameValueCollection nv, string title, HttpContext ctx)
88: {
89: ctx.Response.Write("<HR><B>Secured " + title + " Section</B><BR>");
90: foreach(string key in nv.Keys)
91: {
92: ctx.Response.Write(key + "<BR>");
93: }
94: }
95: }
96: }
97:



All rights reserved. All details are the personal opinion of Scott Cate.
All trademarks referenced are the property of their respective owners.
Scott Cate is a lead programmer for www.myKB.com and
owner of The Arizona .NET User Group and an all around nice guy ;)


Knowledge Base Software - myKB.com