IIS10 URL Rewrite 2.1 双重编码问题

Jor*_*ins 4 iis reverse-proxy url-rewriting url-rewrite-module iis-10

我有一个带有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>
Run Code Online (Sandbox Code Playgroud)

发送以下 URL 时:

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 重写在我的重写之后再次对 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,但指向 localhost:

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 Rewrite 版本中,当尝试使用 UNENCODED_URL 时,URL Rewrite 将对它进行编码,如果原始 URL 已经编码,则可能会导致双重编码。这违反了 RFC3986 的第 2.4 节,其中规定“实现必须不要多次对同一字符串进行百分比编码或解码,因为解码已经解码的字符串可能会导致将百分比数据八位字节误解为百分比编码的开头,或者在对已经百分比编码的情况下反之亦然编码字符串。” 它还使得 UNENCODED_URL 的使用变得不切实际,特别是在使用 ARR 的反向转发器场景中,其中后端服务器期望 URL 未经修改地传递。

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

这里有人知道如何做吗?

Jor*_*ins 5

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

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

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