Redirect to https through url rewrite in IIS withi

2019-01-21 09:24发布

How do you use IIS's url rewrite module to force users to use ssl while you are behind an elastic beanstalk load balancer?

4条回答
霸刀☆藐视天下
2楼-- · 2019-01-21 10:08

This is more difficult than it sounds for a few reasons. One, the load balancer is taking care of ssl so requests passed from the load balancer are never using ssl. If you use the traditional rewrite rule you will get an infinite loop of redirects. Another issue to contend with is that the AWS healthcheck will fail if it receives a redirect response.

  1. The first step in the solution is to create a healthcheck.html page and set it in the root directory. It doesn't matter what the content is.
  2. Set your load balancer to use the healthcheck.html file for health checks.
  3. Add the rewrite rule below in your web.config's <system.webServer><rewrite><rules> section:

    <rule name="Force Https" stopProcessing="true">
       <match url="healthcheck.html" negate="true" />
       <conditions>
           <add input="{HTTP_X_FORWARDED_PROTO}" pattern="https" negate="true" />
       </conditions>
       <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" />
    </rule>
    

Notice that the rule match is on anything but our healthcheck file. This makes sure the load balancer's health check will succeed and not mistakenly drop our server from the load.

The load balancer passes the X-Forwarded-Proto value in the header which lets us know if the request was through https or not. Our rule triggers if that value is not https and returns a permanent redirect using https.

查看更多
啃猪蹄的小仙女
3楼-- · 2019-01-21 10:08

Luke's answer works perfect if you are using an ELB but will not work with an ALB. For an ALB Ross Pace answer is correct. But you can also combine the two so that way you can access the site locally without being redirected to HTTPS.

<rule name="Redirect to HTTPS" enabled="true" stopProcessing="true">
    <match url="healthcheck.html" negate="true" />
        <conditions>
            <add input="{HTTP_X_FORWARDED_PROTO}" pattern="https" negate="true"/>
            <add input="{REMOTE_HOST}" pattern="localhost" negate="true"/>
            <add input="{REMOTE_ADDR}" pattern="127.0.0.1" negate="true"/>
            <add input="{HTTP_HOST}" pattern="localhost" negate="true"/>
        </conditions>
    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent"/>
</rule>
查看更多
放我归山
4楼-- · 2019-01-21 10:09

This worked for my application - IIS 8.5, redirect HTTP to HTTPS behind an AWS ALB. The key was adding appendQueryString="false" to prevent the query string duplication on redirect. You can add the traps for health check and localhost processing as needed. I did not need to add the health check trap, as we added this to the web.config of the app, making it app specific. Our health check is the default app on the domain, so it was not affected.

  <system.webServer>
  <rewrite>
  <rules>
          <rule name="Redirect to HTTPS" enabled="true" stopProcessing="true">
              <match url="^(.*)$" />
              <conditions>
                  <add input="{HTTP_X_FORWARDED_PROTO}" pattern="https" negate="true"/>
              </conditions>
              <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" appendQueryString="false" redirectType="Permanent"/>
          </rule>
      </rules>
  </rewrite>

查看更多
混吃等死
5楼-- · 2019-01-21 10:21

Firstly I want to thank Ross for his original answer, it set me on my way to building up an IIS URL Rewrite rule that worked for me by using my existing HTTP to HTTPS redirect rule that I used before my website was behind an AWS Elastic Load Balancer.

<rule name="Redirect to HTTPS" enabled="true" stopProcessing="true">
    <match url="(.*)" />
    <conditions>
        <add input="{HTTP_X_FORWARDED_PROTO}" pattern="https" negate="true" />
        <add input="{REMOTE_HOST}" pattern="localhost" negate="true" />
        <add input="{REMOTE_ADDR}" pattern="127.0.0.1" negate="true" />
        <add input="{HTTP_HOST}" pattern="localhost" negate="true" />
    </conditions>
    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>

This rule allows you to access your site locally within Visual Studio or on the server on port 80 without having to access over HTTPS, so you only have to have a binding for port 80 on the server. It doesn't suffer from the things that others have mentioned (Duplicated querystring etc.).

I personally haven't had any issue with the health check, I didn't need to create a file on the server for the elastic load balancer to ping. I have my load balancer set to health check on TCP:80 and it works.

查看更多
登录 后发表回答