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. My web.config
contains this:
<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.
By default, IIS is configured not to allow you to do this - the <access>
element under system.webServer/security
is locked by default. 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. Up until recently, this startup task has always successfully prevented that error, enabling my SSL configuration to work.
But it's no longer working, and as far as I can tell, this happened when I switched to the 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. And it's a 500.19. (The 500 is 'internal server error' of course, but the .19 signifies that it's a configuration error.)
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.
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). 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.
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. 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. 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:
[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.
I'm not entirely clear on how appcmd.exe
knows which particular web site it's supposed to be configuring. There are several - I've got IIS proper on this box, and there's also a non-Azure-related IIS Express site configured. 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
:
[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?