我最近升级到了Azure 2.1 SDK,在计算机模拟器上运行时,我现在遇到了部分网络角色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角色中的其他所有内容都可以使用 - 只有当我尝试访问SSL配置设置所适用的/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
应该做的事情,但它似乎停止了工作。
我确实发现问题可能在于它正在获取appcmd.exe
的IIS版本,即使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
这可能是相关的吗?
我的脚本中是否缺少解锁配置部分的内容?
答案 0 :(得分: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的全局设置,这两者似乎都没有对IIS的实例产生任何影响Azure模拟器主机。 (我猜这是最近的行为更改,可能与Azure SDK 2.1中的新功能有关,可以实现非高级开发。)
让我担心的是我无法找到任何提及此预定义APPCMD
变量的文档。我只是通过在启动命令脚本中添加以下内容来发现它:
%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe "gci env: | format-list" > c:\temp\env.log
我暂时添加了这个并运行了Web角色,它提供了所有环境变量的完整转储。查看该列表,APPCMD
变量是唯一包含定位正确配置所需信息的变量。但是启动任务的文档似乎建议直接指向AppCmd.exe
的IIS副本 - Use AppCmd.exe to Configure IIS at Startup文章只是硬编码路径。我想如果我在模拟器中启用了完整的IIS,那会有效,但我真的不想这样做。
因此,虽然这个解决方案有效(并且似乎是唯一可行的解决方案,考虑到启动任务环境中的内容)但它让我感到紧张,因为它是一个无证的功能。如果你偶然发现了这个答案,请小心 - 它可能不可靠。