【问题标题】:IIS Reverse Proxy Re-Encoding URLs Containing Percent Sign (%)IIS 反向代理重新编码包含百分号 (%) 的 URL
【发布时间】:2014-03-04 00:16:29
【问题描述】:

我正在尝试使用 IIS 7.5、Application Request Routing 3.0 (ARR) 和 URL Rewrite 2.0 为 Jenkins 设置反向代理。

我的代理大部分都在工作,但遇到了包含百分号 (%) 的 URL 的问题。

无论我尝试什么,代理都会坚持对重写后的 URL 中的百分号进行解码或重新编码。

这就是我希望重写 URL 的方式:

http://my.proxy/a%2Fb -> http://my.host:8080/a%2Fb

这就是 实际上重写 URL 的方式:

http://my.proxy/a%2Fb -> http://my.host:8080/a/b
- or -
http://my.proxy/a%2Fb -> http://my.host:8080/a%252Fb

如何让 IIS\ARR\Rewrite 停止重新编码我重写的 URL?

我尝试过的事情:

  1. 一个普通的反向代理(将 URL 重写为http://my.host:8080/a/b):

    <rule name="ReverseProxyInboundRule1" stopProcessing="true"> <match url="(.*)" ignoreCase="true" /> <action type="Rewrite" url="http://my.host:8080/{R:1}" /> </rule>

  2. 使用UNENCODED_URL 服务器变量(将URL 重写为http://my.host:8080/a%252Fb):

    <rule name="ReverseProxyInboundRule1" stopProcessing="true"> <match url="(.*)" ignoreCase="false" /> <conditions logicalGrouping="MatchAll"> <add input="{UNENCODED_URL}" pattern="/(.*)" /> </conditions> <action type="Rewrite" url="http://my.host:8080/{C:1}" /> </rule>

  3. 直接输入 URL(作为测试 - 还将 URL 重写为 http://my.host:8080/a%252Fb):

    <rule name="ReverseProxyInboundRule1" stopProcessing="true"> <match url="(.*)" ignoreCase="false" /> <action type="Rewrite" url="http://my.host:8080/a%2Fb" /> </rule>

  4. Scott Hanselman 出色的“Experiments in Wackiness: Allowing percents, angle-brackets, and other naughty things in the ASP.NET/IIS Request URL”中的所有想法

    1. &lt;httpRuntime requestValidationMode="2.0" requestPathInvalidCharacters="*,:,&amp;amp;,\" relaxedUrlToFileSystemMapping="true" /&gt;
    2. <security> <requestFiltering allowDoubleEscaping="true" /> </security>'

注意:当我的 IIS 反向代理与 Jenkins' built-in reverse proxy checking system 发生冲突时,我遇到了这种行为,Jenkins' built-in reverse proxy checking system 试图将 HTTP 重定向到此表单的 URL。

【问题讨论】:

  • 你有没有想过这个问题?我现在也有同样的问题...
  • 不幸的是,没有。出于这个原因,我不再将 IIS 视为可接受的反向代理平台。
  • 你改用了什么?
  • @Martin - 我一直使用 Apache。我试图在 Windows 机器上切换到 IIS,但没有成功。

标签: iis urlencode reverse-proxy url-rewrite-module arr


【解决方案1】:

Joseph,这是我尝试解决完全相同的问题的所有方法的一个很好的总结,让带有 SSL 的 IIS 将流量路由到我的 Gerrit 实例。当我找到您的帖子时,我希望也许有人想出了一种配置它的神奇方法,但我想这是不可能的。我又尝试了一件事,我为 IIS 编写了一个自定义重写提供程序,这样我就可以在路由完成之前对百分号进行解码,但后来我意识到编码发生在以后,这是没有意义的(我忘记了你的步骤nr 3 显示它非常好)。

但是我不能像以前那样摆脱 IIS,所以我想出了一个解决方法。我已经实现了一个简单的服务,它充当 IIS 和 Gerrit 之间的附加代理。当您像在步骤 2 中那样配置 IIS 时,转发的请求将获得 %25 代替 url 中的百分比字符。 IIS 没有到达 Gerrit,而是将请求转发到代理服务。该服务将所有出现的%25 更改为%(解码百分比)并将其转发给Gerrit。无需对响应进行任何操作。对于那些想走这条路的人,你可以从我在 C# 中简单实现代理开始:

https://gist.github.com/gralin/b5edfd908a41fc7268a7757698af1e66

【讨论】:

    【解决方案2】:

    我能够使用第二种方法并设置useOriginalURLEncoding="false"来解决这个问题:

    <rules useOriginalURLEncoding="false">
        <rule name="ReverseProxyInboundRule1" stopProcessing="true">
            <match url="(.*)" ignoreCase="false" />
            <conditions logicalGrouping="MatchAll">
                <add input="{UNENCODED_URL}" pattern="/(.*)" />
            </conditions>
            <action type="Rewrite" url="http://my.host:8080/{C:1}" />
        </rule>
    </rules>
    

    有关背景信息,另请参阅official blog postuseOriginalURLEncoding的措辞有点可惜。

    【讨论】:

      【解决方案3】:

      我曾认为使用带有 % 符号的 url 的代理有问题,但之后我发现它不是。代理地址过长的问题。

      我使用带有选项服务器端的数据表:true 和类型:GET。然后,当从服务器加载内容时,代理 url 太长,就会出现问题。我已经改进了 url 请求的大小,问题已经解决。

      <system.webServer>
          <security>
              <requestFiltering>
                  <requestLimits maxQueryString="4000" maxUrl="2000" />
              </requestFiltering>
          </security>
          <rewrite>...</rewrite>
          ...
      </system.webServer>
      

      但请记住,允许长查询字符串和 url 存在安全风险,此外,这是一个糟糕的设计。

      【讨论】:

        猜你喜欢
        • 2020-09-05
        • 2021-11-08
        • 1970-01-01
        • 1970-01-01
        • 2016-11-13
        • 1970-01-01
        • 2013-01-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多