URL 重写条件可以比较两个服务器变量吗?

MAL*_*n84 5 rewrite iis-7.5 arr outboundrules

我正在尝试将两个服务器变量作为 URL 重写条件的一部分进行比较。但首先,一些背景...

在 IIS 中,如果您请求http://www.example.com/foo并且foo是一个目录,则 IIS 会将 302“移动对象”重定向http://www.example.com/foo/作为“礼貌重定向”(Source)发送到。

如果您使用 IIS+ARR 作为具有 SSL 卸载的反向代理,后端 IIS 节点接收的请求是通过 http 而不是 https。

结合这两种行为,IIS 的礼貌重定向会丢弃 SSL。礼貌重定向使用与 IIS 收到的请求()相同的方案,在这种情况下是 http 而不是 https。

我想创建一个出站重写规则,将传入 URL 与传出 Location 标头进行比较,并在这种情况下将其从 http 重写为 https:

  • 响应是重定向:{RESPONSE_STATUS}是 302
  • 传入的请求是通过 SSL: {HTTPS}is "on"
  • 传入的 URL 不以斜杠结尾。
  • 传出的 Location 标头以斜杠结尾。

以上都是在前提条件下处理的。棘手的部分是最后一点:

  • 传出 Location 标头的路径与传入 URL 相同,并附加了斜杠。

下面是我到目前为止的代码。前提条件和标头重写都可以正常工作。但是,该条件会导致 500 错误(URL 重写模块错误),大概是因为我{REQUEST_URI}在模式中使用。我尝试将条件分成两个并使用捕获组,但这也不起作用。有任何想法吗?

<rule name="Fix: Courtesy Redirect + SSL Offloading = SSL dropped" preCondition="Courtesy Redirect Drops SSL" enabled="true">
    <match serverVariable="RESPONSE_LOCATION" pattern="^http://(.+/)$" />
    <conditions>
        <add input="{RESPONSE_LOCATION}" pattern="{REQUEST_URI}/" />
    </conditions>
    <action type="Rewrite" value="https://{R:1}" />
</rule>
<preConditions>
    <preCondition name="Courtesy Redirect Drops SSL">
        <add input="{RESPONSE_STATUS}" pattern="^302$" />
        <add input="{HTTPS}" pattern="^on$" />
        <add input="{REQUEST_URI}" pattern=".*[^/]$" />
        <add input="{RESPONSE_LOCATION}" pattern="^http://.+/$" />
    </preCondition>
</preConditions>
Run Code Online (Sandbox Code Playgroud)

小智 3

您可以使用自定义重写提供程序。提供程序是将一个字符串转换为另一个字符串的 C# 代码。然后,您可以按照与使用重写映射类似的方式使用它:

您可以选择在 url 中根本无效的分隔符。(也许使用空格或类似的东西。我将使用它,|以便它在本文中可见,但您应该选择其他字符串。)

您将编写一条规则来设置服务器变量的值IsItMatching。服务器变量的值将使用您的自定义 url 重写提供程序进行设置:

{provider_name:{server_variable_1}|{server_variable_2}}
Run Code Online (Sandbox Code Playgroud)

然后,实现提供程序的 C# 代码将执行此操作(伪代码,无错误检查):

{provider_name:{server_variable_1}|{server_variable_2}}
Run Code Online (Sandbox Code Playgroud)

然后,您将再编写一条规则来检查服务器变量的值IsItMatching是“yes”还是“no”。