August 16 2012

IIS URL Rewrite - Redirect multiple domains to one and http to https with a single rule

Redirecting multiple domains to one and http to https is a pretty common requirement, and the are plenty of examples online showing how to do this using the IIS URL Rewrite Module.

Most of the examples I've seen work fine, but use separate rules for redirecting each domain and for redirecting http to https, resulting in something like this:

<rewrite>
    <rules>
        <rule name="Redirect .net to .com" patternSyntax="Wildcard" stopProcessing="true">
            <match url="*" />
            <conditions>
                <add input="{HTTP_HOST}" pattern="mydomain.net" />
            </conditions>
            <action type="Redirect" url="http://mydomain.com/{R:0}" />
        </rule>
        <rule name="Redirect www to non-www" patternSyntax="Wildcard" stopProcessing="true">
            <match url="*" />
            <conditions>
                <add input="{HTTP_HOST}" pattern="www.mydomain.com" />
            </conditions>
            <action type="Redirect" url="http://mydomain.com/{R:0}" />
        </rule>
        <rule name="Redirect http to https" patternSyntax="Wildcard" stopProcessing="true">
            <match url="*" />
            <conditions>
                <add input="{HTTPS}" pattern="off" ignoreCase="true" />
            </conditions>
            <action type="Redirect" url="https://mydomain.com/{R:0}" />
        </rule>
    </rules>
</rewrite>

The problem with this is that multiple rules are used to satisfy what is really just a single requirement: "I want all requests for my site to go to https://mydomain.com, regardless of the domain the user typed in".

Refactoring the above, we're able to reduce it to a single rule:

<rewrite>
    <rules>
        <rule name="Redirect everything to https://mydomain.com" patternSyntax="Wildcard" stopProcessing="true">
            <match url="*" />
            <conditions logicalGrouping="MatchAny">
                <add input="{HTTP_HOST}" pattern="mydomain.com" negate="true" />
                <add input="{HTTPS}" pattern="off" ignoreCase="true" />
            </conditions>
            <action type="Redirect" url="https://mydomain.com/{R:0}" />
        </rule>
    </rules>
</rewrite>

This is done with the help of the negate attribute, which effectively changes the first condition to catch any request that is NOT for the domain "mydomain.com", so there's no longer a need to check for each different domain.


Sponsored by