Friday, August 31, 2007

Redirecting HTTP to HTTPS

I recommend using the IIRF isapi filter for performing HTTP to HTTPS redirects. You can find the project at http://www.codeplex.com/IIRF/. I've successfully used this isapi filter for some of my projects.

The syntax of IIRF is very similar to the mod_rewrite for Apache. Googling for "RewriteRule AND https" retrieved some valuable samples and tutorials:

  • http://www.whoopis.com/howtos/apache-rewrite.html
  • http://wiki.apache.org/httpd/RewriteHTTPToHTTPS
  • http://www.karkomaonline.com/article.php/2005080614195334

  • I'm sure there are more terse ways to write the regular expressions. However, this should provide a good start.

    Make sure the folder exists and set logging to max while debugging.
    ------- 8< ------- >8 -------
    RewriteLog c:\temp\iirfLog.out
    RewriteLogLevel 5
    ------- 8< ------- >8 -------

    These are the rules I use on our dev box called "PEER". Some of the apps require the full server and domain name. These sets of rules expand the name from "PEER" to the complete domain "peer.dev.us.company.com". Since I'm not an expert on regex I use the logical OR to concatenate the rules.
    ------- 8< ------- >8 -------
    RewriteCond %{HTTPS} on
    #RewriteCond %{SERVER_PORT} ^443$
    RewriteCond %{HTTP_HOST} ^peer$ I,OR
    RewriteCond %{HTTP_HOST} ^peer\:0-9*$ I,OR
    RewriteCond %{HTTP_HOST} ^peer.dev.us.company.com\:0-9*$ I
    RewriteRule ^/(.*)$ https://peer.dev.us.company.com/$1 R
    ------- 8< ------- >8 -------

    #tests to see if the connection is already HTTPS
    RewriteCond %{HTTPS} on

    #since we only have one https site, I ignore this. Useful for more than one site.
    #RewriteCond %{SERVER_PORT} ^443$

    #was the server typed in as just "PEER".
    #I - ignore case
    #OR - logical OR with the rule below
    RewriteCond %{HTTP_HOST} ^peer$ I,OR

    #was the server typed in as "PEER" plus some port?
    #
    I - ignore case
    #OR - logical OR with the rule below
    RewriteCond %{HTTP_HOST} ^peer\:0-9*$ I,OR

    #was the server typed in as "peer.dev.us.company.com" plus some port?
    #I - ignore case
    #OR - logical OR with the rule below
    RewriteCond %{HTTP_HOST} ^peer.dev.us.company.com\:0-9*$ I

    #Redirect to the https site with the fully qualified name.
    #Keep the path the user specified.
    #
    So if a user types in "http://peer/reports" they are
    #redirected to "http://peer.dev.us.company.com/reports"
    RewriteRule ^/(.*)$ https://peer.dev.us.company.com/$1 R




    This rule redirects all port 80 requests to the https site. I've seen the rule written as "^!443$", which means all connections on ports other than 443 are redirected to the https site. I used port 80, because we have test sites on other ports which don't require SSL.
    ------- 8< ------- >8 -------
    RewriteCond %{SERVER_PORT} ^80$
    RewriteRule ^/(.*)$ https://www.company.com/$1 R
    ------- 8< ------- >8 -------