Easy Steps to Use HTTPS in IIS ASP.NET Environment – Windows ASP.NET Core Hosting 2020 | Review and Comparison

Google is urging more and more webmasters to move their sites to HTTPS for security reasons. We learned a few tricks along the way. Once you’ve done it once it becomes pretty straightforward, but getting the big picture and handling every detail well is not trivial. So I hope this post will be useful.

HTTPS and Google Analytics Referrals

One reason for moving to HTTPS is that Google Analytics referrals don’t work when the user comes from a HTTPS website. And since most of your referrers websites are likely to be already HTTPS, if you keep up with HTTP, your GAnalytics becomes blind.

Notice that once you’ve moved to HTTPS, you still won’t be able to track referrers that come from an HTTP url, which is annoying since most of the time you don’t have edit-access to these urls.

Getting the Certificate

You can get free certificates from LetsEncrypt.com and you can find providers that offer FREE SSL on our blog. The renewal process can certainly be automated. In other way, you can always purchase SSL certificate. There are many providers that offer SSL certificate, for example Godaddy, Gandi, ASPHostPortal. Their price are pretty cheap.

When ordering the certificate, a CSR (Certificate Sign Request) will be requested. The CSR can be obtained from IIS as explained here for example, through the menu Generate Certificate Request. A few questions about who you are will be asked, the most important being the Common Name, which will be typically www.yourdomain.com  (or, better, use a wildcard, as in *.yourdomain.com). If the Common Name doesn’t match the web site domain, the user will get a warning at browsing time, so this is a sensitive step.

Installing the Certificate in IIS

Once you’ve ordered the certificate, the certificate shop will provide you with a .crt or .cer crypted content. This is the certificate. But IIS doesn’t deal with the .crt nor .cer formats, it asks for a .pfx file! Basically you’ll use the IIS menu Complete Certificate Request (that follows the first Generate Certificate Request). Now restart IIS or the server to make sure it’ll take care of the certificate.

Binding the Certificate to the website 443 Port in IIS

At that point the certificate is installed on the server. The certificate needs to be bound with your website port 443. First make sure that the port 443 is opened on your server, and second, use the binding IIS menu on your website. A binding entry will have to be added as shown in the picture below.

Once added just restart the website. Normally, you can now access your website through HTTPS urls. If not, you may have to tweak the DNS pointers somehow, but I cannot comment since we didn’t have a problem with that.

At that point, both HTTPS and HTTP are browsable. HTTP requests need to be redirected to HTTPS to complete the migration.

Important: Subtilty when updating your renewed certificate

When renewing your certificate you will obtain a new certificate with an extended expiration date but with the same common name (remember common name is like www.yourdomain.com). When importing the new certificate in your IIS server store, you will end up with two certificates with the same common name.

To bind your site with the new certificate, in the site binding form you will have to select the new certificate. However the old and new certificate are both shown with the same common name (www.yourdomain.com in the screenshot below). This is awkward since there is no expiration date to tell you which one is the newer!!

Once you choose one, double-check from your browser that your site certificate date has been updated with the new one. To do so, as shown by the screenshot below click certificate and check the expiration date. Once checked you can then safely delete the old certificate from your store.

301 redirection with Web.Config and IIS UrlRewriter

HTTP to HTTPS redirection can be achieved by modifying the Web.Config file of your ASP.NET website, to tell the IIS Url rewriter how to redirect. After a few attempts based on googling, our redirection rules look like:

  <system.webServer>
    <rewrite>
      <rules>
        <clear />
        <rule name="Redirect to https" stopProcessing="true">
          <match url=".*" />
          <conditions>
            <add input="{HTTPS}" pattern="off" ignoreCase="true" />
            <add input="{URL}" pattern="(.*)XYZ" negate="true" ignoreCase="true"/>             
            <add input="{HTTP_HOST}" matchType="Pattern" pattern="^localhost(:\d+)?$" negate="true" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
        </rule>
        <rule name="redirect yourdomain.com to www.yourdomain.com">
          <match url=".*"/>
          <conditions logicalGrouping="MatchAll">
            <add input="{HTTP_HOST}" pattern="^www.*" negate="true"/>
            <add input="{HTTP_HOST}" pattern="localhost" negate="true"/>
          </conditions>
          <action type="Redirect" url="http://www.yourdomain.com/{R:0}"/>
        </rule>
      </rules>
    </rewrite>
  </system.webServer>

If you believe this can be improved, please let me know. At least it works 🙂

  • <add input=”{HTTPS}” pattern=”off” ignoreCase=”true” /> is the main redirection rule that redirects HTTP requests to HTTPS (this is called 301 redirection). You’ll find many sites on the web to test that your 301 redirection works fine.
  • Make sure to double check that urls with GET params are redirected well. On our side, url=“https://{HTTP_HOST}{REQUEST_URI}” processes GET params seamlessly
  • <add input=”{URL}” pattern=”(.*)XYZ” negate=”true” ignoreCase=”true”/> is important to avoid HTTP to HTTPS redirection for a page named XYZ. Typically, if you have special pages with POST requests, they might be broken with the HTTPS redirection, and thus the redirection needs to be discarded for those.
  • <add input=”{HTTP_HOST}” matchType=”Pattern” pattern=”^localhost(:\d+)?$” negate=”true” /> avoid the HTTPS redirection when testing on localhost.
  • <add input=”{HTTP_HOST}” pattern=”^www.*” negate=”true”/> just transforms yourdomain.com requests into www.yourdomain.com,
  • and  <add input=”{HTTP_HOST}” pattern=”localhost” negate=”true”/> avoids this WWW redirection on localhost.

Eliminate Mixed Content

At this point you are almost done. Yet depending on the topology of your web site(s) and resources, it is possible that some pages generate a mixed content warning. Mixed content means that some resources (like images or scripts) of an HTTPS web page are served through HTTP. When mixed content is detected, most browsers show a warning to users about a not fully secured page.

You’ll find tools to search for mixed content on your web site, but you can also crawl the site yourself and use the Chrome console to get details about mixed content found.

Update Google SiteMap and Analytics

Finally make sure that your Google sitemap now references HTTPS urls, and update your Google Analytics for HTTPS.

It is easy, right?

I hope this content saves a few headaches. I hope this post can be useful for you and feel free to share this article.

Thank you. Happy coding!