0
votes

TLDR: I just need this one condition: https://www.example.com -> https://example.com

I have rewrite rules which are working to Force HTTPS. I also need to enforce www to non-www (or figure out if there is a way to change the binding so that https://www also works). I am dynamically installing and binding multiple SSL's for multiple domains to the site using Server Name Indication (SNI) when IIS starts. Therefore, I don't know what the URL is going to be. I believe I have figured out how to use the condition callbacks to capture the authority part {example.com} and drop the www.

However, if the user types https://www.example.com, I can't get that to match. Using the pattern matching tool in the IIS url rewrite module on the server, the https://www.example.com pattern does seem to match, but it isn't actually triggering the rule in the browser. Something about the https in the browser is throwing it off? Or is it my bindings?

<rewrite>
  <rules>
    <rule name="Rewrite http www to https">
      <match url="(.*)" ignoreCase="true" />
      <conditions logicalGrouping="MatchAll">
        <add input="{HTTP_HOST}" matchType="Pattern" pattern="www" />
        <add input="{HTTP_HOST}" matchType="Pattern" pattern="^(www\.)(.*)$" />
      </conditions>
      <action type="Redirect" url="https://{C:2}/{R:1}" appendQueryString="true" redirectType="Found" />
    </rule>

    <!-- This rule is not working.  It never seems to match. -->
    <rule name="Rewrite https www to https">
      <match url="(.*)" ignoreCase="true" />
      <conditions logicalGrouping="MatchAll">
        <add input="{HTTP_HOST}" matchType="Pattern" pattern="www" />
        <add input="{HTTP_HOST}" matchType="Pattern" pattern="^(https://)(www\.)(.*)$" />
      </conditions>
      <action type="Redirect" url="https://{C:3}/{R:1}" appendQueryString="true" redirectType="Found" />
    </rule>

    <rule name="Force HTTPS" enabled="true">
       <match url="(.*)" ignoreCase="true" />
       <conditions>
           <add input="{HTTPS}" pattern="off" />
       </conditions>
       <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Found" />
    </rule>
  </rules>           
</rewrite>

So, to recap, currently the rules do this:

http://example.com -> https://example.com (good)

https://example.com -> https://example.com (good)

http://www.example.com -> https://example.com (good)

https://www.example.com -> https://www.example.com !!! (should be https://example.com)

My bindings are currently:
type - host name - port - ip address
http - blank - 80 - 10.0.0.53
https - example.com - 443 - *
https - example2.com - 443 - *

2
So I'm gonna give another take on this.. You should only use www or non-www urls. What kind of service is it?Magnus Karlsson
First, thanks so much for commenting. I was losing faith in SO. I agree I only want to use non-www. When the user types www, I'm struggling with how to force them to the non-www version. I'm not sure what you mean by service. It's a Razor MVC C# website being ran on Windows Server 2012 IIS.phpmeh
I tried locally and rules work. First rule will redirect www to non www even for http or https, second rule will be ignored due to invalid condition and third rule will ensure https. Are you sure this is no a browser caching issue ?Cyril Durand

2 Answers

1
votes

My answer is that you shouldn't use url rewrites to get https and www.

I put [RequireHttps] on the controller classes that should use https (or the method if you have methods in that controller that should respond to plain http requests).

Doing so will solve the problems with non-www and www with http and https.

Then as for your additional comment that you only want to use www, I usually just set that up with CNAME and A record with the DNS provider but that is another question.

1
votes

The answer ended up being incredibly simple... My bindings at the end of the post had to be changed.

type - host name - port - ip address

 http - blank - 80 - 10.0.0.53
 https - example.com - 443 - *
 https - example2.com - 443 - * 
 https - www.example.com - 443 - *
 https - www.example2.com - 443 - *