我最近升级到Azure 2.1 SDK,现在在计算模拟器上运行时,我在Web角色中遇到部分web.config问题。我的web.config包含以下内容:

<location path="api">
  <system.webServer>
    <security>
      <access sslFlags="Ssl, SslRequireCert, SslNegotiateCert" />
    </security>
  </system.webServer>
  <system.web>
    <authorization>
      <allow users="*" />
    </authorization>
  </system.web>
</location>

我需要这样做,因为/api/路径下的所有内容都要求客户端通过通过HTTPS提供客户端证书来进行身份验证。

默认情况下,IIS配置为不允许您执行此操作-缺省情况下,<access>下的system.webServer/security元素被锁定。因此,我一直都有一个包含以下内容的启动任务:
SET APPCMD=%windir%\system32\inetsrv\appcmd.exe
IF EXIST APPCMD GOTO :INUSUALPLACE
SET APPCMD="%ProgramFiles%\IIS Express\appcmd.exe"
:INUSUALPLACE
%APPCMD% unlock config /section:system.webServer/security/access

否则,您将收到500.19错误。直到最近,此启动任务始终成功阻止了该错误,从而使我的SSL配置能够正常工作。

但是,它不再起作用了,据我所知,这是在我切换到2.1 SDK时发生的。该Web角色中的其他所有内容都可以正常工作-只有当我尝试在SSLt设置设置所适用的/api/路径下访问服务时,才会出现错误。这是500.19。 (当然500是“内部服务器错误”,但.19表示这是配置错误。)

据我所知,这是因为尝试解锁此配置部分不再有效。我之所以这么说是因为,如果我找到了Azure模拟器创建的applicationHost.config文件(在C:\Users\<user>\AppData\Local\dftmp\Resources\<some random guid>\temp\temp\RoleTemp中),并且我手动对其进行编辑,将Deny元素的security替换为Allow,那么我将停止获取错误,并且可以成功使用需要客户端证书的服务。

当然,这没有用作为解决方法-每次在模拟器中运行应用程序时都会重新生成此applicationHost.config(并且每次都会更改确切的位置)。每当我在本地调试应用程序时,我都需要某种方法来自动可靠地解锁此配置部分。这就是appcmd.exe应该执行的操作,但似乎已停止工作。

我确实想到了问题可能是它正在获取IISt的appcmd.exe,即使Azure SDK现在使用IIS express。我不确定它们是否是不同的程序,因此我尝试在启动命令的末尾添加以下内容:
"%ProgramFiles%\IIS Express\appcmd.exe" unlock config /section:system.webServer/security/access

这将显式运行IIS Express副本。但这似乎没有任何区别。

在任何人要求之前,启动任务肯定正在运行。在与applicationHost.config相同的文件夹中,我看到一个WaHostBootstrapper.log文件,该文件包含(其中包括)以下几行:
[00025156:00018324, 2013/08/30, 22:15:03.033, INFO ] Executing Startup Task type=0 rolemodule=(null) cmd="c:\dev\mm\DevInt\src\Mm.Cloud\csx\Debug\roles\Mm.Web\approot\bin\Startup\EnableClientCerts.cmd"
[00025156:00018324, 2013/08/30, 22:15:03.034, INFO ] Executing "c:\dev\mm\DevInt\src\Mm.Cloud\csx\Debug\roles\Mm.Web\approot\bin\Startup\EnableClientCerts.cmd" .
[00025156:00018324, 2013/08/30, 22:15:03.221, INFO ] Program "c:\dev\mm\DevInt\src\Mm.Cloud\csx\Debug\roles\Mm.Web\approot\bin\Startup\EnableClientCerts.cmd"  exited with 0. Working Directory = c:\dev\mm\DevInt\src\Mm.Cloud\csx\Debug\roles\Mm.Web\approot\bin

这表明我的EnableClientCerts.cmd(调用appcmd.exe的脚本)已正确运行。

对于appcmd.exe如何知道应该配置哪个特定网站,我还不太清楚。有几个-我在此框上具有IIS的正确名称,并且还配置了一个非Azure相关的IIS Express站点。是否有可能无法配置正确的目标?

另外,我在WaHostBootstrapper.log中看到了一些此类错误:
[00025156:00018324, 2013/08/30, 22:15:03.033, ERROR] <- WapGetEnvironmentVariable=0x800700cb

这可能有关吗?

我的脚本中是否缺少用于解锁配置部分的内容?

最佳答案

事实证明,当仿真器启动启动任务时,它已经设置了APPCMD变量。此外,它不仅将其设置为引用AppCmd.exe,还包括指向正确的配置文件的命令行开关:
"C:\Program Files\IIS Express\appcmd.exe" /apphostconfig:"C:\Users\Ian\AppData\Local\dftmp\Resources\1217ef49-a59a-4e18-8ebc-27d06a78cbd5\temp\temp\RoleTemp\applicationHost.config"
因此,如果启动脚本仅使用%APPCMD%而不先尝试对其进行设置,则它将应用于正确的实例。我的脚本无法正常运行,因为它自行决定AppCmd.exe的位置,最终将修改IIS或IIS Express的全局设置,而这两者似乎都不会影响Azure仿真器托管的IIS实例。 (我猜想这是行为上的最新变化,可能与启用非高架开发的Azure SDK 2.1的新功能有关。)

令我担心的是,我找不到任何提及此预定义APPCMD变量的文档。我只是通过将以下内容添加到启动命令脚本中来发现它的:

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe "gci env: | format-list"  > c:\temp\env.log

我临时添加了该角色并运行了Web角色,它提供了所有环境变量的完整转储。浏览该列表时,APPCMD变量是唯一包含定向正确配置所需的信息的变量。但是启动任务的文档似乎建议直接指向IIS的AppCmd.exe副本-Use AppCmd.exe to Configure IIS at Startup文章只是对路径进行了硬编码。我想如果在模拟器中启用了完整的IIS,那将是可行的,但是我并不是真的想要这样做。

因此,尽管此解决方案有效(并且鉴于启动任务环境中的情况,它似乎是唯一可行的解​​决方案),但它使我感到紧张,因为它是一个未记录的功能。因此,如果您偶然发现了这个答案,请小心-它可能不可靠。

关于asp.net - 为什么appcmd.exe解锁配置在Azure模拟器上不起作用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18541845/

10-11 05:05