Optimal HTTP to HTTPS Redirect Implementation for IIS 10: A Server-Wide Solution


2 views

While individual site configuration via 'Require SSL' with 403 error handlers works technically, it presents significant administrative overhead:

  • Manual repetition across multiple sites
  • Potential configuration drift
  • 302 temporary redirects instead of SEO-friendly 301s

IIS URL Rewrite module provides the most elegant server-wide solution. Here's how to implement:

<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="HTTP to HTTPS Redirect" stopProcessing="true">
          <match url="(.*)" />
          <conditions>
            <add input="{HTTPS}" pattern="^OFF$" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

1. ApplicationHost.config Level

Add the rewrite rule directly in %windir%\system32\inetsrv\config\applicationHost.config within the <system.webServer> section. This applies to all sites.

2. Web.config Inheritance

Place the rule in a root-level web.config that child applications inherit from.

<rule name="Force HTTPS with Port Preservation">
  <match url="(.*)" />
  <conditions logicalGrouping="MatchAny">
    <add input="{HTTPS}" pattern="^OFF$" />
    <add input="{SERVER_PORT}" pattern="^80$" />
  </conditions>
  <action type="Redirect" 
          url="https://{HTTP_HOST}:{SERVER_PORT}/{R:1}" 
          redirectType="Permanent" />
</rule>

After implementation, verify with:

  • curl -I http://yoursite.com (should return 301)
  • Browser developer tools network tab
  • SSL test tools like SSL Labs

The URL Rewrite module adds minimal overhead. For high-traffic servers:

  • Consider HTTP.sys kernel-mode caching
  • Monitor rewrite rule processing time in IIS logs

Many IIS administrators configure SSL redirection at the individual website level by:

<system.webServer>
    <security>
        <access sslFlags="Ssl" />
    </security>
    <httpErrors>
        <error statusCode="403" subStatusCode="4" 
               path="/redirect.aspx" responseMode="ExecuteURL" />
    </httpErrors>
</system.webServer>

While functional, this method becomes tedious when managing multiple sites and increases configuration errors.

For IIS 7+ with URL Rewrite module installed, implement this in applicationHost.config:

<configuration>
    <system.webServer>
        <rewrite>
            <globalRules>
                <rule name="Global HTTPS Redirect" patternSyntax="Wildcard">
                    <match url="*" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                        <add input="{HTTPS}" pattern="off" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" 
                            redirectType="Permanent" />
                </rule>
            </globalRules>
        </rewrite>
    </system.webServer>
</configuration>

Create a web.config in your server root (typically C:\inetpub\wwwroot):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Force HTTPS" enabled="true" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions logicalGrouping="MatchAny">
                        <add input="{HTTPS}" pattern="^OFF$" />
                        <add input="{SERVER_PORT}" pattern="^80$" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>
  • Test with 302 redirects first before switching to 301
  • Clear browser cache during testing
  • Monitor IIS logs for redirect loops
  • Combine with HSTS header for maximum security:
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <add name="Strict-Transport-Security" 
                     value="max-age=31536000; includeSubDomains" />
            </customHeaders>
        </httpProtocol>
    </system.webServer>
    

Use these PowerShell commands to verify:

# Check if URL Rewrite module is installed
Get-WindowsFeature Web-URL-Auth

# Test redirect (returns 301 status)
Invoke-WebRequest -Uri "http://yoursite.com" -Method Head | Select-Object StatusCode