X-ARR-ClientCert 未从 Azure Web App 反向代理传递到另一个 Azure Web App

X-ARR-ClientCert 未从 Azure Web App 反向代理传递到另一个 Azure Web App

我在 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 更新他们的文档以进一步讨论这个问题。

相关内容