我在 Azure Web App 实例中设置了一个反向代理,该代理重写 URL 并强制 SSL 到我们的主要 Azure Web App .NET 应用程序。它运行良好。
我们想要将客户端证书身份验证部署到此 .NET 应用程序。我们已将其直接应用于 .NET 应用程序的 Azure Web App 实例,但我们需要它通过 Azure Web App 反向代理。
反向代理似乎正在接收X-ARR-ClientCert
信息(我可以在故障跟踪中看到它),但并未将这些信息传递给主 Web 服务器。我到处寻找,但找不到任何证据表明这是不可能的。事实上,这应该是完全可能的,而且有很多帖子说人们在 IIS 中成功做到了这一点。
我想知道我是否只是遇到了一个愚蠢的配置错误web.config
,或者这是否是未记录的 Azure Web App 的限制。
任何帮助或见解都将非常有帮助。这是我的web.config
文件,其中 mainazurewebapp.azurewebsites.com 是我们的主要 .NET 应用程序,如果您直接访问该应用程序并使用客户端证书进行身份验证,它就可以正常工作。
<system.webServer>
<security>
<requestFiltering removeServerHeader="true"/>
</security>
<httpProtocol>
<customHeaders>
<clear />
<add name="X-Frame-Options" value="SAMEORIGIN" />
<add name="X-Xss-Protection" value="1; mode=block" />
<add name="X-Content-Type-Options" value="nosniff" />
</customHeaders>
</httpProtocol>
<httpErrors errorMode="Detailed" />
<rewrite>
<rules>
<rule name="ForceSSL" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
<rule name="Proxy" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="https://mainazurewebapp.azurewebsites.net/{R:1}"/>
<serverVariables>
<set name="HTTP_X_UNPROXIED_URL" value="https://mainazurewebapp.azurewebsites.net/{R:1}" />
<set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="{HTTP_ACCEPT_ENCODING}" />
<set name="HTTP_X_ORIGINAL_HOST" value="{HTTP_HOST}" />
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="Add Strict-Transport-Security only when using HTTPS" enabled="true">
<match serverVariable="RESPONSE_Strict_Transport_Security" pattern=".*" />
<conditions>
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
</conditions>
<action type="Rewrite" value="max-age=31536000; includeSubdomains; preload" />
</rule>
<rule name="ChangeReferencesToOriginalUrl" patternSyntax="ExactMatch" preCondition="CheckContentType">
<match filterByTags="None" pattern="https://mainazurewebapp.azurewebsites.net" />
<action type="Rewrite" value="https://{HTTP_X_ORIGINAL_HOST}" />
</rule>
<preConditions>
<preCondition name="CheckContentType">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^(text/html|text/plain|text/xml|application/rss\+xml)" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
答案1
解决了!在与 Azure 支持人员(他们的能力令人耳目一新)反复发邮件后,我们得到了修复。
主要问题是我们的反向代理 Azure Web 实例位于 Azure 的负载均衡器后面,这意味着我们在技术上位于“另一个”反向代理后面。因此,当我们的反向代理接收 X-ARR-CLIENTCERT 标头时,它无法将其转发到其后面的主要应用程序。
解决方案是将 X-ARR-CLIENTCERT 标头重写为临时标头,然后更新我们的 .net 应用程序以从该临时标头而不是默认的 X-ARR-CLIENTCERT 读取。
所以我们必须更新我们的 xdt 文件来添加
<add name="HTTP_X_PRIVATE_TOKEN" xdt:Transform="InsertIfMissing" xdt:Locator="Match(name)" />
然后编辑我们的 web.config 文件以添加
<set name="HTTP_X_PRIVATE_TOKEN" value="{HTTP_X_ARR_CLIENTCERT}" />
然后我们的代码只需读取 HTTP-X-PRIVATE-TOKEN,一切就设置好了。
我花了很多时间试图解决这个问题,并想把答案发布在这里以供后人参考。我已要求 MS 更新他们的文档以进一步讨论这个问题。