如何在SSL终止反向代理后运行时在IIS上创建重定向响应?

时间:2014-11-13 09:04:40

标签: asp.net iis ssl reverse-proxy

我有一个ASP.NET网站,通常通过HTTPS在IIS上运行。现在我想把它放在一个反向代理后面,它会为我做SSL终止。问题是来自反向代理的请求是在HTTP:80上,当我按照惯例创建重定向响应时,响应的Location标头设置为http://...而不是{{1 }}

我知道反向代理在标题中传递了https://...,我可以在创建重定向响应时检查该标头,并重定向一般的URL。但是,如果可能的话,我希望避免在代码周围为X-Forwarded-Proto分配检查,并在编码时再考虑一下,还必须仔细检查一切是否仍然有效它部署在代理服务器后面。

1 个答案:

答案 0 :(得分:6)

我发现的最好方法是使用IIS URL重写模块并设置HTTPSSERVER_PORT标头,以便代理网站甚至不知道它在代理后面工作。我在Web.config中使用了以下配置:

<rewrite>
    <allowedServerVariables>
        <add name="HTTPS" />
        <add name="SERVER_PORT" />
    </allowedServerVariables>
    <rules>
        <rule name="backend" patternSyntax="Wildcard">
            <match url="*" />
            <conditions>
                <add input="{HTTP_X_FORWARDED_PROTO}" pattern="https" />
            </conditions>
            <serverVariables>
                <set name="HTTPS" value="on" />
                <set name="SERVER_PORT" value="443" />
                </serverVariables>
            <action type="None" />
        </rule>
    </rules>
</rewrite>

上述部分指出,只要传入请求将X-Forwarded-Proto设置为https,就应设置服务器变量HTTPSSERVER_PORT以模仿来自HTTPS的请求。有了这个配置,我不必在我自己的代码中对X-Forwarded-Proto进行任何检查。

请注意,URL重写模块是在管道末尾调用的,特别是它在HTTP重定向模块之后运行。如果使用此模块或任何其他IIS级别机制重定向,则构造的URL仍将具有错误的方案。到目前为止,我的修复方法是重新实现所有IIS级重定向以使用URL重写模块,而不是其他任何内容。

另请注意,通常无法从应用程序级<allowedServerVariables>文件设置Web.config部分。您将需要解锁部分才能访问应用程序,或者您需要在根网站的配置中直接配置此部分。这是我用于在Web节点上安装和配置URL重写的脚本:

Param(
    [string] $package = 'rewrite_2.0_rtw_x64.msi'
)

Start-Process -Wait msiexec -ArgumentList @('/i', $package, '/quiet', '/qn', '/norestart')

$applicationHost = "C:\Windows\System32\inetsrv\config\applicationHost.config"

$config = [xml](Get-Content $applicationHost)

$webServer = $config.configuration.configSections.sectionGroup | where {$_.name -eq "system.webServer"}
$rewrite = $webServer.sectionGroup | where {$_.name -eq "rewrite"}
$serverVariables = $rewrite.section | where {$_.name -eq "allowedServerVariables"}
$serverVariables.SetAttribute("overrideModeDefault", "Allow")

$config.Save($applicationHost)