【问题标题】:IIS10 URL Rewrite 2.1 double encoding issueIIS10 URL Rewrite 2.1 双编码问题
【发布时间】:2018-04-19 03:39:16
【问题描述】:

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

这样的服务器之一是Jenkins

Jenkins 有一条警告消息告诉您反向代理是否配置正确 (more details here),这条警告消息帮助我找到了反向代理中的问题。

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

示例:

网址重写规则:

<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} 在解码之前获取请求字符串,所以我调整了我的规则动作:

&lt;action type="Rewrite" url="http://localhost:8080{UNENCODED_URL}" appendQueryString="false" /&gt;

不幸的是,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/&lt;parameter1&gt;

在哪里&lt;parameter1&gt; = https%3A%2F%2Fjenkins.mydomain%2Fmanage%3F

&lt;parameter1&gt; 中的斜线字符经过编码,以便 Jenkins 可以知道 path 的一部分是什么,&lt;parameter1&gt; 是什么。

这意味着,当 URL 重写解码 URL 时,&lt;parameter1&gt;path 的其余部分混合在一起。

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

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

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

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

在 v7.1.1980 之前的 URL Rewrite 版本中,当尝试使用 UNENCODED_URL, URL Rewrite 将对其进行编码,这可能导致双重 如果原始 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


    【解决方案1】:

    您可以使用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>
    

    【讨论】:

    • 它不起作用,因为之前编码的斜线字符不会被编码。如果您仔细查看请求 url,您会注意到最后一段是:/https%3A%2F%2Fjenkins.mydomain%2Fmanage%3F 其中:%2F = /
    • 嗯,我找不到任何区别。您能否尝试将Rewrite 字更改为Redirect 并比较该结果与/ 有问题
    • 重定向的问题与以前相同。我编辑了这个问题。真正的问题是编码的斜杠字符属于参数而不是 Jenkins 中的页面。
    • 好的,也许最好在您的问题中包含预期结果。你想要达到的目标
    • 目标是获得与浏览器发送的完全相同的 URL,但指向 localhost:8080。我刚刚用这些信息更新了问题。
    【解决方案2】:

    我通过设置我在问题中引用的帖子中描述的useOriginalURLEncoding = false 设法解决了这个问题。

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

    将该标志设置为 false,当在规则中使用 {UNENCODED_URL} 变量时,URL Rewrite 将不再对 URL 进行编码。

    【讨论】:

    • 你值得拥有一座雕像!我一直在寻找解决这个问题的几个小时。非常感谢!
    猜你喜欢
    • 2023-01-17
    • 1970-01-01
    • 2020-06-29
    • 2021-07-19
    • 2011-09-23
    • 2021-02-25
    • 2011-10-14
    • 2010-11-14
    • 1970-01-01
    相关资源
    最近更新 更多