为什么appcmd.exe解锁配置无法在Azure模拟器上运行?

Ian*_*ths 7 asp.net iis ssl azure ssl-certificate

我最近升级到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>
Run Code Online (Sandbox Code Playgroud)

我需要这个,因为/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
Run Code Online (Sandbox Code Playgroud)

没有它,你会得到500.19错误.直到最近,此启动任务始终成功阻止该错误,使我的SSL配置能够正常工作.

但它不再有效,据我所知,当我切换到2.1 SDK时就发生了这种情况.此Web角色中的其他所有内容都适用 - 只有当我尝试访问/api/SSL配置设置所应用的路径下的服务时才会出现错误.这是一个500.19.(当然,500是'内部服务器错误',但.19表示这是配置错误.)

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

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

appcmd.exe虽然Azure SDK现在使用IIS express,但我确实发现问题可能是它正在拿起IIS版本.我不确定它们是否是不同的程序,所以我尝试在我的启动命令结束时添加它:

"%ProgramFiles%\IIS Express\appcmd.exe" unlock config /section:system.webServer/security/access
Run Code Online (Sandbox Code Playgroud)

这显式运行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
Run Code Online (Sandbox Code Playgroud)

这表明我的EnableClientCerts.cmd(调用的脚本appcmd.exe)运行没有错误.

我不清楚如何appcmd.exe知道它应该配置哪个特定的网站.有几个 - 我在这个盒子上有正确的IIS,并且还配置了一个非Azure相关的IIS Express站点.是否有可能无法配置正确的目标?

另外,我在下面看到了一些这样的错误WaHostBootstrapper.log:

[00025156:00018324, 2013/08/30, 22:15:03.033, ERROR] <- WapGetEnvironmentVariable=0x800700cb
Run Code Online (Sandbox Code Playgroud)

这有关系吗?

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

Ian*_*ths 7

事实证明,当模拟器启动启动任务时,它已经设置了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
Run Code Online (Sandbox Code Playgroud)

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

因此,虽然这个解决方案有效(并且似乎是唯一可行的解​​决方案,考虑到启动任务环境中的内容)但它让我感到紧张,因为它是一个无证的功能.如果你偶然发现了这个问题,请小心 - 它可能不可靠.

  • 我最终得到了这个"前提条件":如果没有定义APPCMD SET APPCMD =%SystemRoot%\ system32\inetsrv\AppCmd.exe (4认同)