IIS反向代理重新编码包含百分号的URL(%)

时间:2014-03-04 00:16:30

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

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

我的代理主要工作,但遇到包含百分号(%)的网址的问题。

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

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

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

这就是实际重写网址的方式:

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. 只需直接输入网址(作为测试 - 也将网址重写为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. <httpRuntime requestValidationMode="2.0" requestPathInvalidCharacters="*,:,&amp;,\" relaxedUrlToFileSystemMapping="true" />
    2. <security> <requestFiltering allowDoubleEscaping="true" /> </security>'
  5. 注意:当我的IIS反向代理与Jenkins' built-in reverse proxy checking system发生冲突时,我遇到了这种行为,它试图将HTTP重定向到此表单的URL。

3 个答案:

答案 0 :(得分:2)

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

然而,我无法摆脱IIS,所以我想出了一个解决方法。我已经实现了一个简单的服务,充当IIS和Gerrit之间的附加代理。在步骤2中配置IIS时,转发的请求将获取%25来代替网址中的百分比字符。 IIS不会到达Gerrit,而是将请求转发给代理服务。该服务将所有出现的%25更改为%(解码百分比)并将其转发给Gerrit。响应没有什么需要做的。对于那些想要这样做的人,你可以从我在C#中简单实现代理开始:

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

答案 1 :(得分:0)

我曾经想过使用带有url的代理包含%符号有问题,但之后我发现它不是。代理URL过长的问题。

我使用带有选项服务器端的数据表:true并输入:GET。然后,当使用代理URL加载来自服务器的内容太长时,就会出现问题。我已经改进了网址请求的大小,问题已修复。

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

但请记住,允许长查询字符串和网址是一种安全风险,更重要的是,这是一个糟糕的设计。

答案 2 :(得分:0)

我能够使用第二种方法并设置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的措词有点不幸。