Adam
Adam

Reputation: 6122

IIS rewrite rule Redirect Non-www to dynamic Domain Equivalent and always https

What I want is that all requests that are non-https or don't have www prepended are redirected to: "https://www." + domain name + possible query string parameters.

I have this rewrite rule (found here):

<rule name="non-www to www https" enabled="true" stopProcessing="true">
  <match url=".*" />
  <conditions>
    <add input="{HTTP_HOST}" pattern="^[^\.]+\.[^\.]+$" />
    <add input="{HTTPS}" pattern="on" />
  </conditions>
  <action type="Redirect" url="https://www.{HTTP_HOST}/{R:0}" />
</rule>

However, when typing the following domains in the browser address bar no redirect takes place (and I get a security certificate error since I don't have a wildcard DNS SSL certificate):
https://example.com/
http://example.com/

But example.com (without protocol), redirects correctly to https://www.example.com/

Also notice in the above rule that I'm matching the hostname dynamically and not just on "example.com" since I want this rule to work for multiple domain names.

I then also checked this post, which has a neat rule:

<rule name="Force WWW and SSL" enabled="true" stopProcessing="true">
  <match url="(.*)" />
  <conditions logicalGrouping="MatchAny">
      <add input="{HTTP_HOST}" pattern="^[^www]" />
      <add input="{HTTPS}" pattern="off" />
  </conditions>
  <action type="Redirect" url="https://www.zzz.com/{R:1}" appendQueryString="true" redirectType="Permanent" />
</rule>

I think this does exactly what I want, but how would I make the domain name in this example dynamic and preserve that in the redirect (like the first code sample does)? (the original poster has not logged in in the last 6 months so that's why I am asking here)

Furthermore I also checked this post, which also seems a good candidate:

<rule name="Redirect top domains with non-www to www" stopProcessing="true">
      <match url="(.*)" />
      <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="{HTTP_HOST}" pattern=".*localhost.*" negate="true" />
        <add input="{HTTP_HOST}" pattern=".*stage\..*" negate="true" />
        <add input="{HTTP_HOST}" pattern=".*dev\..*" negate="true" />
        <add input="{HTTP_HOST}" pattern="^([^\.]+)\.([^\.]+)$" />
      </conditions>
      <action type="Redirect" url="https://www.{HTTP_HOST}/{R:1}" redirectType="Permanent" />
      <serverVariables>
        <set name="Redirect" value="false" />
      </serverVariables>
 </rule>


<rule name="Force HTTPS" enabled="true" stopProcessing="true">
      <match url="(.*)" ignoreCase="false" />
      <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="{HTTP_HOST}" pattern=".*localhost.*" negate="true" />
        <add input="{HTTP_HOST}" pattern=".*stage\..*" negate="true" />
        <add input="{HTTP_HOST}" pattern=".*dev\..*" negate="true" />
        <add input="{HTTPS}" pattern="off" />
      </conditions>
      <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" />
 </rule>

But then http://example.com redirects to https://example.com and I still get the security exception.

Upvotes: 4

Views: 1041

Answers (1)

Kul-Tigin
Kul-Tigin

Reputation: 16950

First, I strongly recommend you to obtain a new SSL certificate that supports both example.com and www.example.com. That kind of certificates are actually pretty standard with most SSL providers, it does not have to be a wildcard certificate. Otherwise you will not be able to handle requests to https://example.com as it is now, and that's a problem I think.

Your top two rules should be like the ones below.

P.S. 301 redirects are cached for a while by the browsers. Google clear 301 redirect cache for your browser before testing the new rules.

<rule name="All HTTP to HTTPS+WWW" stopProcessing="true">
    <match url=".*" />
    <conditions trackAllCaptures="true">
        <add input="{SERVER_PORT_SECURE}" pattern="0" />
        <add input="{HTTP_HOST}" pattern="(?:localhost|stage\.|dev\.)" negate="true" />
        <!-- here with this 3rd condition we capture the host name without "www." prefix into {C:1} variable to use in redirect action -->
        <add input="{HTTP_HOST}" pattern="^(?:www\.)?(.+)" />
    </conditions>
    <action type="Redirect" url="https://www.{C:1}/{R:0}" appendQueryString="true" redirectType="Permanent" />
</rule>                
<rule name="All HTTPS With No WWW to HTTPS+WWW" stopProcessing="true">
    <match url=".*" />
    <conditions trackAllCaptures="false">
        <add input="{SERVER_PORT_SECURE}" pattern="1" />
        <add input="{HTTP_HOST}" pattern="(?:localhost|stage\.|dev\.)" negate="true" />
        <add input="{HTTP_HOST}" pattern="^www\." negate="true" />
    </conditions>
    <action type="Redirect" url="https://www.{HTTP_HOST}/{R:0}" appendQueryString="true" redirectType="Permanent" />
</rule>

Upvotes: 3

Related Questions