IIS10 URL Rewrite 2.1 双重编码问题

问题描述 投票:0回答:3

我有一个带有 ARR 3.0 和 URL 重写模块 2.1 的 IIS10 服务器,它充当其他几个 Web 服务器的反向代理。其他服务器运行在不同的端口上,因此 IIS10 服务器在端口 80 上提供“友好 URL”。 URL 重写用于将请求交给后端服务器。

这样的服务器之一是 Jenkins

Jenkins 有一条警告消息,告诉您反向代理是否配置良好(此处有更多详细信息),此警告消息帮助我找到了反向代理中的问题。

问题是 URL 重写正在对我的 URL 进行解码和编码,当它们到达 Jenkins 时,它们与浏览器请求的不同。

示例:

URL重写规则:

<rule name="Jenkins Rewrite" stopProcessing="true">
   <match url="(.*)" />
   <conditions>
     <add input="{HTTP_HOST}" pattern=".*jenkins.mydomain.*" />
     <add input="{HTTPS}" pattern="on" />
   </conditions>
   <action type="Rewrite" url="http://localhost:8080/{R:1}" appendQueryString="true" />
   <serverVariables>
     <set name="HTTP_X_FORWARDED_HOST" value="{HTTP_HOST}" />
     <set name="HTTP_X_FORWARDED_SCHEMA" value="https" />
     <set name="HTTP_X_FORWARDED_PROTO" value="https" />
   </serverVariables>
 </rule>

发送以下网址时:

https://jenkins.mydomain/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https%3A%2F%2Fjenkins.mydomain%2Fmanage%3F

我注意到编码字符在触发规则之前被解码,使得 {R:1} 看起来像这样:

/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https:/jenkins.mydomain/manage/

经过一番研究,我发现我可以使用 {UNENCODED_URL} 而不是 {R:1} 在解码之前获取请求字符串,所以我调整了我的规则操作:

<action type="Rewrite" url="http://localhost:8080{UNENCODED_URL}" appendQueryString="false" />

不幸的是,URL Rewrite 在我的 Rewrite 之后再次对 URL 进行编码,使得 Jenkins 收到的 URL 被双重编码:

/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https%253A%252F%252Fjenkins.mydomain%252Fmanage%253F

简短摘要:

当您查看此网址时:

/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https%3A%2F%2Fjenkins.mydomain%2Fmanage%3F

我们拥有的是:

/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/<parameter1>

哪里

<parameter1> = https%3A%2F%2Fjenkins.mydomain%2Fmanage%3F

<parameter1>
中的斜杠字符被编码,以便Jenkins可以知道
path
的一部分以及
<parameter1>
是什么。

这意味着,当 URL 重写解码 URL 时,

<parameter1>
会与
path
的其余部分混合。

期望的结果是获取与浏览器发送的 URL 完全相同的 URL,但指向本地主机:

http://localhost:8080/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https%3A%2F%2Fjenkins.mydomain%2Fmanage%3F

是否有办法禁用 URL 重写模块正在执行的解码/编码操作?

PS:我发现了一篇关于 URL Rewrite v2.1 功能的博客文章,它说有一个新标志可用于禁用此行为,但我不知道如何或在哪里设置它。

在 v7.1.1980 之前的 URL 重写版本中,当尝试使用 UNENCODED_URL,URL重写会对它进行编码,这可能会导致双重 如果原始 URL 已经编码,则进行编码 这是违规的 RFC3986 第 2.4 节的规定,其中规定“实现不得 对同一字符串进行多次百分比编码或解码,如解码 已解码的字符串可能会导致错误解释百分比数据 八位字节作为百分比编码的开头,反之亦然 对已经进行百分比编码的字符串进行百分比编码的情况。” 使得 UNENCODED_URL 的使用变得不切实际,尤其是在反向时 具有 ARR 的转发器场景,其中后端服务器需要 URL 不加修改地通过。

在 v7.1.1980 中,我们添加了一个功能标志,useOriginalURLEncoding 允许您在设置时关闭此不兼容的 URL 编码 为真。默认行为将保持不变 (useOriginalURLEncoding 默认为 true)。

这里有人知道如何做吗?

iis url-rewriting reverse-proxy url-rewrite-module iis-10
3个回答
5
投票

我设法通过设置我在问题中引用的帖子中描述的

useOriginalURLEncoding = false
解决了这个问题。

要将标志设置为

IIS Manager
,然后选择
Configuration Editor
并转到
system.webServer/rewrite/rules
部分,您将在其中找到
useOriginalURLEncoding
标志。

将该标志设置为 false,当在规则中使用

{UNENCODED_URL}
变量时,URL 重写将不再对 URL 进行编码。


0
投票

您可以使用

UrlEncode
功能来实现这一点。将规则更改为:

<action type="Rewrite" url="http://localhost:8080/{UrlEncode:{R:1}}" appendQueryString="true" />

更新: 解决问题的另一种方法

<rule name="Jenkins Rewrite" stopProcessing="true">
   <match url="(.*)" />
   <conditions>
        <add input="{UNENCODED_URL}" pattern="(.*)" />
         <add input="{HTTP_HOST}" pattern=".*jenkins.mydomain.*" />
         <add input="{HTTPS}" pattern="on" />
    </conditions>
    <action type="Rewrite" url="http://localhost:8080{C:1}" appendQueryString="true" />
   <serverVariables>
     <set name="HTTP_X_FORWARDED_HOST" value="{HTTP_HOST}" />
     <set name="HTTP_X_FORWARDED_SCHEMA" value="https" />
     <set name="HTTP_X_FORWARDED_PROTO" value="https" />
   </serverVariables>
 </rule>

0
投票

要解决此问题,您需要在

useOriginalURLEncoding="false"
<globalRules>
部分中组合
<rules>
标志,并确保以未编码形式使用 URL。

下面是阻止 IIS 解码您的 URL 的工作规则示例:

<system.webServer>
  <rewrite>
    <globalRules useOriginalURLEncoding="true">
      <rule name="TestRule">
          <action type="Rewrite" url="{UNENCODED_URL}" />
      </rule>
    </globalRules>
  </rewrite>
</system.webServer>

此外,您可能需要启用

<requestFiltering allowDoubleEscaping="true" />
来处理包含斜杠
(/)
等特殊字符的 URL。

此方法可确保 URL 按预期传递,而不会被 IIS 解码。

© www.soinside.com 2019 - 2024. All rights reserved.