简体   繁体   English

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

[英]Why is appcmd.exe unlock config not working on Azure emulator?

I've recently upgraded to the Azure 2.1 SDK, and I'm now encountering a problem with part of my web.config in a web role when running on the compute emulator. 我最近升级到了Azure 2.1 SDK,现在我在计算模拟器上运行时遇到了web角色中部分web.config的问题。 My web.config contains this: 我的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>

I need this because everything under the /api/ path requires clients to authenticate by providing client-side certificates over HTTPS. 我需要这个,因为/api/ path下的所有内容都要求客户端通过HTTPS提供客户端证书进行身份验证。

By default, IIS is configured not to allow you to do this - the <access> element under system.webServer/security is locked by default. 默认情况下,IIS配置为不允许您执行此操作 - 默认情况下, system.webServer/security下的<access>元素已被锁定。 So I've always had a startup task that contains this: 所以我总是有一个包含这个的启动任务:

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

Without that, you would get a 500.19 error. 没有它,你会得到500.19错误。 Up until recently, this startup task has always successfully prevented that error, enabling my SSL configuration to work. 直到最近,此启动任务始终成功阻止该错误,使我的SSL配置能够正常工作。

But it's no longer working, and as far as I can tell, this happened when I switched to the 2.1 SDK. 但它不再有效,据我所知,当我切换到2.1 SDK时就发生了这种情况。 Everything else in this web role works by the way - it's only when I try to access the services under the /api/ path to which the SSL configuration settings apply that I get an error. 此Web角色中的其他所有内容都是顺便运行的 - 只有当我尝试访问SSL配置设置所适用的/api/ path下的服务时才会出现错误。 And it's a 500.19. 这是一个500.19。 (The 500 is 'internal server error' of course, but the .19 signifies that it's a configuration error.) (当然,500是'内部服务器错误',但.19表示这是配置错误。)

As far as I can tell, it's happening because the attempt to unlock this configuration section is no longer working. 据我所知,它正在发生,因为尝试解锁此配置部分已不再有效。 The reason I say that is that if I find the applicationHost.config file that the Azure emulator creates (in C:\\Users\\<user>\\AppData\\Local\\dftmp\\Resources\\<some random guid>\\temp\\temp\\RoleTemp ) and I manually edit it, replacing the Deny for the security element with an Allow , I stop getting the error, and can successfully use the services that require client certificates. 我说的原因是,如果我找到Azure模拟器创建的applicationHost.config文件(在C:\\Users\\<user>\\AppData\\Local\\dftmp\\Resources\\<some random guid>\\temp\\temp\\RoleTemp并且我手动编辑它,用Allow替换security元素的Deny ,我停止获取错误,并且可以成功使用需要客户端证书的服务。

That's no use as a workaround of course - this applicationHost.config is regenerated each time you run the app in the emulator (and the exact location changes each time). 当然,这不是一种解决方法 - 每次在模拟器中运行applicationHost.config都会重新生成此applicationHost.config (每次确切的位置都会更改)。 I need some way to reliably unlock this configuration section automatically each time I debug the application locally. 每次我在本地调试应用程序时,我都需要一些方法来自动解锁此配置部分。 That's what appcmd.exe is supposed to do, but it seems to have stopped working. 这就是appcmd.exe应该做的,但它似乎停止了工作。

It did occur to me that the problem might be that it's picking up the IIS version of appcmd.exe , even though the Azure SDK now uses IIS express. 它确实发生在我的问题可能是它正在拿起IIS版本的appcmd.exe ,即使Azure SDK现在使用IIS express。 I'm not sure if they're different programs, so I tried adding this at the end of my startup command: 我不确定它们是否是不同的程序,所以我尝试在我的启动命令结束时添加它:

"%ProgramFiles%\IIS Express\appcmd.exe" unlock config /section:system.webServer/security/access

This explicitly runs the IIS Express copy. 这显式运行IIS Express副本。 But it doesn't seem to make any difference. 但它似乎没有任何区别。

The startup task is definitely running, before anyone asks. 在任何人问之前,启动任务肯定在运行。 In the same folder as the applicationHost.config , I see a WaHostBootstrapper.log file, and it contains (amongst other things) these lines: 在与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

This indicates that my EnableClientCerts.cmd (the script that calls appcmd.exe ) ran without error. 这表明我的EnableClientCerts.cmd (调用appcmd.exe的脚本)运行没有错误。

I'm not entirely clear on how appcmd.exe knows which particular web site it's supposed to be configuring. 我不完全清楚appcmd.exe如何知道它应该配置哪个特定的网站。 There are several - I've got IIS proper on this box, and there's also a non-Azure-related IIS Express site configured. 有几个 - 我在这个盒子上有正确的IIS,并且还配置了一个非Azure相关的IIS Express站点。 Is it possible that it's failing to configure the correct target? 是否有可能无法配置正确的目标?

Also, I see a few of this sort of error in the WaHostBootstrapper.log : 另外,我在WaHostBootstrapper.log看到了一些这样的错误:

[00025156:00018324, 2013/08/30, 22:15:03.033, ERROR] <- WapGetEnvironmentVariable=0x800700cb

Could that be related? 这有关系吗?

Is there something missing from my script for unlocking the configuration section? 我的脚本中是否缺少解锁配置部分的内容?

It turns out that when the emulator launches the startup task, it has already set the APPCMD variable. 事实证明,当模拟器启动启动任务时,它已经设置了APPCMD变量。 Moreover, it sets it not just to refer to the AppCmd.exe , it also includes a command line switch that points to the right configuration file: 此外,它不仅指向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"

So if the startup script just uses %APPCMD% without first attempting to set it, it will apply to the correct instance. 因此,如果启动脚本只是使用%APPCMD%而没有先尝试设置它,它将应用于正确的实例。 My script was not working because it made its own decision about where AppCmd.exe was located, and would end up modifying global settings for either IIS or IIS Express, neither of which seem to have any impact on the instance of IIS that the Azure Emulator hosts. 我的脚本无法运行,因为它自己决定AppCmd.exe位置,并最终修改IIS或IIS Express的全局设置,这两者似乎都不会对Azure模拟器的IIS实例产生任何影响主机。 (I'm guessing that this is a recent change in behaviour, possibly relating to the new feature in Azure SDK 2.1 that enables non-elevated development.) (我猜这是最近的行为变化,可能与Azure SDK 2.1中的新功能有关,可以实现非高速开发。)

The thing that worries me about this is that I can't find any documentation that mentions this pre-defined APPCMD variable. 令我担心的是我无法找到任何提及此预定义APPCMD变量的文档。 I only discovered it by adding the following to my startup command script: 我只是通过在启动命令脚本中添加以下内容来发现它:

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

I added that temporarily and ran the web role, and it provided a complete dump of all environment variables. 我暂时添加了该角色并运行了Web角色,它提供了所有环境变量的完整转储。 Looking through that list, the APPCMD variable is the only one that contains the information required to target the correct configuration. 查看该列表, APPCMD变量是唯一包含定位正确配置所需信息的变量。 But the documentation for startup tasks seems to recommend pointing directly at the IIS copy of AppCmd.exe - the Use AppCmd.exe to Configure IIS at Startup article just hardcodes the path. 但是启动任务的文档似乎建议直接指向AppCmd.exe的IIS副本 - 使用AppCmd.exe在启动时配置IIS文章只是硬编码路径。 I guess that would work if I enabled the use of full IIS in the emulator, but I don't really want to do that. 我想如果我在模拟器中启用了完整的IIS,那会有效,但我真的不想这样做。

So although this solution works (and appears to be the only viable solution, given what's in the startup task's environment) it makes me nervous because it's an undocumented feature. 因此,虽然这个解决方案有效(并且似乎是唯一可行的解​​决方案,考虑到启动任务环境中的内容)但它让我感到紧张,因为它是一个无证的功能。 So be careful if you've stumbled upon this answer - it might not be reliable. 如果你偶然发现了这个问题,请小心 - 它可能不可靠。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM