8

我最近升级到 Azure 2.1 SDK,我现在web.config在计算模拟器上运行时遇到了我在 Web 角色中的一部分问题。我的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 角色中的其他所有内容都有效 - 只有当我尝试访问/api/应用 SSL 配置设置的路径下的服务时,我才会收到错误消息。它是 500.19。(当然,500 是“内部服务器错误”,但 .19 表示这是配置错误。)

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

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

我确实想到问题可能是它正在使用 IIS 版本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

这可能有关系吗?

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

4

1 回答 1

8

原来,模拟器在启动启动任务的时候,已经设置了这个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——使用 AppCmd.exe 在启动时配置 IIS文章只是硬编码了路径。我想如果我在模拟器中启用完整的 IIS 会起作用,但我真的不想这样做。

因此,尽管此解决方案有效(并且似乎是唯一可行的解​​决方案,考虑到启动任务的环境中的内容),但它让我感到紧张,因为它是一个未记录的功能。所以如果你偶然发现了这个答案,请小心——它可能不可靠。

于 2013-08-31T07:46:25.547 回答