首页 > 解决方案 > IIS URL Rewrite否定条件设置服务器变量

问题描述

我正在尝试修改添加 HTTPS 服务器变量的长期存在的 IIS 重写规则。从虚拟专用网络上的负载均衡器内部(即网络场内部)访问现有 API 时,这给我带来了一些问题。TLS 在负载均衡器处终止,因此网络内仅支持 HTTP,我不想升级那些内部客户端。我正在尝试添加一些否定条件来排除某些标准。目前的规则如下所示:

<rewrite>
  <rules>
    <rule name="SET_HTTPS" enabled="true">
      <match url=".*" />
      <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
      <serverVariables>
        <set name="HTTPS" value="on" />
      </serverVariables>
      <action type="None" />
    </rule>
  </rules>
</rewrite>

我正在查看的关键条件如下:

  1. HTTPS方案在哪里OFF
  2. 设置X-Forwarded-ProtoHTTPS
  3. 其中HTTP_HOST匹配以结尾的模式.localhost
  4. 其中HTTP_HOST匹配一个等于的模式localhost

第 4 点很好,因为它让我可以在本地开发机器上测试它。第 3 点允许我在负载均衡器后面的 API 之间进行互通。第 2 点帮助我识别来自负载均衡器的现有 HTTPS 连接,而第 1 点向我显示请求来自 HTTP 而不是 HTTPS。

我设计了一个我希望可以工作的规则,但没有。我想我错过了一些简单的东西,但我无法弄清楚。我正在 VS2019 的 IIS Express 上对其进行测试,并添加了以下 applicationHost.config 以允许system.webserver节点内的特定服务器变量:

<rewrite>
    <allowedServerVariables>
        <add name="HTTPS" />
    </allowedServerVariables>
</rewrite> 

目前无效的规则是:

<rewrite>
  <rules>
    <rule name="SET_HTTPS" enabled="true">
      <match url="(.*)" />
      <conditions>
        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
        <add input="{HTTP_X_Forwarded_Proto}" pattern="https" negate="true" ignoreCase="true" />
        <add input="{HTTP_HOST}" negate="true" pattern="^[a-zA-Z-]+\.localhost$" ignoreCase="true" />
        <add input="{HTTP_HOST}" negate="true" pattern="^localhost$" ignoreCase="true" />
      </conditions>
      <serverVariables>
        <set name="HTTPS" value="on" />
      </serverVariables>
      <action type="None" />
    </rule>
  </rules>
</rewrite>

它总是 302 将我重定向到 HTTPS,因此例如在访问 http://localhost:1234 时会忽略最后一个条件。

我错过了什么?此规则必须适用于 IIS7 和 IIS10。也许是订购?

标签: iisurl-rewritingiis-7iis-10

解决方案


这个怎么样:

<rule name="Set HTTPS" enabled="true">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
       <add input="{HTTPS}" pattern="^OFF$" />
       <add input="{HTTP_X_Forwarded_Proto}" pattern="^HTTPS$" ignoreCase="true" negate="true" />
       <add input="{HTTP_HOST}" pattern="^localhost$" negate="true" />
       <add input="{HTTP_HOST}" matchType="Pattern" pattern=".*\.localhost$" ignoreCase="true" negate="true" />
    </conditions>
    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="SeeOther" />
</rule>

我使用这个确切的规则(不包括 HTTP_X_Forwarded_Proto 条件),它就像一个魅力。

PS:在极少数情况下,我们发现一些自定义 web/url 调用者可能会使用服务器端口填充 HTTP_HOST 标头。您应该能够在数据包跟踪中嗅出它,如果是这种情况,您可以将 HTTP_HOST 条件调整得稍微宽松一点。(即 ^localhost$ 将变为 ^localhost* 或 ^localhost:[0-9]+$ )


推荐阅读