With the Windows Azure SDK 1.3 comes full support for IIS in web roles, giving your web roles the ability to access the full range of web service features available in IIS.  This provides a lot of powerful capabilities, some of which are outlined here.

By default, the AppPool runs as the NetworkService.  Go ahead and create a new Windows Azure Project, choose a web role, and hit F5 to run it in IIS.  A new AppPool is created with a GUID for the name, and you’ll see that the Identity is NetworkService.

DefaultAppPoolIdentity

In most cases this is fine, and the NetworkService identity is sufficient.  However, there are some cases where you many need to change the AppPool identity.  Here at Microsoft, for example, we have an internal proxy that manages all our network traffic.  In order for traffic to move through the proxy, the underlying identity has to be an authenticated domain user.  Consequently, any requests sent by the NetworkService result in errors when trying to access network resources (e.g. Windows Azure storage, AppFabric service namespaces, and SQL Azure).

Since we cannot proactively change the settings used to create the AppPool, we need to make the change immediately following it’s creation but before our application starts to run.  Consequently, we’ll use the OnStart() method in the WebRole’s role entry point (i.e. WebRole.cs).

First, you’ll need to add a reference to two assemblies:

  1. System.DirectoryServices
  2. Microsoft.Web.Administration (found in C:WindowsSystem32inetsrv)

Now, update the OnStart() method with the following code:

Code Snippet
  1. public override bool OnStart()
  2. {
  3.     // For information on handling configuration changes
  4.     // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
  5.  
  6.     var webApplicationProjectName = "Web";
  7.     var appPoolUser = "northamerica\\wwegner";
  8.     var appPoolPass = "password";
  9.     var metabasePath = "IIS://localhost/W3SVC/AppPools";
  10.  
  11.     using (ServerManager serverManager = new ServerManager())
  12.     {
  13.         var appPoolName = serverManager.Sites[RoleEnvironment.CurrentRoleInstance.Id + "_" + webApplicationProjectName].Applications.First().ApplicationPoolName;
  14.  
  15.         using (DirectoryEntry appPools = new DirectoryEntry(metabasePath))
  16.         {
  17.             using (DirectoryEntry devFabricAppPool = appPools.Children.Find(appPoolName, "IIsApplicationPool"))
  18.             {
  19.                 if (devFabricAppPool != null)
  20.                 {
  21.                     devFabricAppPool.InvokeSet("AppPoolIdentityType", new Object[] { 3 });
  22.                     devFabricAppPool.InvokeSet("WAMUserName", new Object[] { appPoolUser });
  23.                     devFabricAppPool.InvokeSet("WAMUserPass", new Object[] { appPoolPass });
  24.                     devFabricAppPool.Invoke("SetInfo", null);
  25.  
  26.                     devFabricAppPool.CommitChanges();
  27.                 }
  28.             }
  29.         }
  30.     }
  31.  
  32.     return base.OnStart();
  33. }

 

A few things to point out:

  • Line #6: Specify the name of your web role project as webApplicationProjectName.  This is used on line #13 to look up the newly created AppPool.

image

  • Lines #7 & #8: Update to use your own username & password.
  • Line #21: The AppPoolIdentityType of 3 means we’re providing a custom username & password.

Once you update your code and run again, you’ll see that your AppPool is updated with the new identity.

NewAppPoolIdentity

Now, whenever your application makes a request through the network, it will originate from your domain account (or whatever you specify) instead of the NetworkService.

WARNING: I should point out that there is one negative side effect that I’ve noticed when changing the identity of the AppPool programmatically – it will prevent the debugger from working normally.  I don’t (yet) know of a way to resolve this, but I’m still looking.

I hope this helps!

  • Pingback: Programmatically Changing the AppPool Identity in a Windows Azure Web Role « Ricardo Villalobos' Blog

  • Pingback: Windows Azure AppPool Settings Programmatic Modification - Andy Cross

  • Ryan

    Another idea – I found that I can use “bitsadmin” to set the proxy for networkservice to an instance of fiddler running as me. Fiddler can, by virtue of running as me, talk to the interent. Debugging works for me with this setup.

    bitsadmin /util /SETIEPROXY NETWORKSERVICE MANUAL_PROXY 127.0.0.1:8888 NULL

    • Rob Potter

      This works for me.

      When you start Fiddler, it sets the WinINET proxy for the logged on user to 127.0.0.1:8888. However, the Dev Fabric sets the IIS App Pool to run as NETWORK SERVICE and so this does not know of any proxy config and does not route HTTP requests through Fiddler. Therefore, I have been getting DNS resolution failure when using this Azure storage connection string: “UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://ipv4.fiddler”.

      By running “bitsadmin /util /SETIEPROXY NETWORKSERVICE MANUAL_PROXY 127.0.0.1:8888 NULL”, NETWORK SERVICE now uses Fiddler as a proxy, resolves ipv4.fiddler to localhost, and traces all my HTTP traffic to and from the dev storage emulator.

  • Pingback: Persisting IIS Logs in Windows Azure SDK v1.3 | Convective

  • http://www.l1id.com Howard Hoffman

    Wade’s point about picking up Microsft.Web.Administration.dll from %windir%system32inetsrv is *very* important. On my Windows 7 box, the version of this DLL is 7.0.0.0. The IIS Express installer also places a copy of this DLL into GAC, marked version 7.9.0.0.

    If you happen to add a reference from your project to the 7.9.0.0 copy of Microsft.Web.Administration.dll, you get strange errors about not finding applicationHost.config in a path rooted from c:users (e.g. the %USERPROFILE% path). By referencing the native IIS copy (7.0.0.0), the implementation attempts to open the correct applicationHost.config file (correct for Azure, that is) at %windir%system32inetsrvconfig.

  • http://blogs.msdn.com/chgeuer/ Christian Geuer-Pollmann

    One thing to mention is that for the original code to work, you must have the “IIS Metabase and IIS 6 configuration compatibility” installed. If you do not have that installed, you’ll run into fancy COMExceptions. The pure IIS7 solution would be like below. Besides that, you might also have to ‘hammer’ the config change if you run multiple web roles.

    string appPoolUser = GetDevelopmentMachineSettingFromRegistry(“DomainUserName”);
    string appPoolPass = GetDevelopmentMachineSettingFromRegistry(“DomainPassword”);

    Action iis7fix = (appPoolName) =>
    {
    bool committed = false;
    while (!committed)
    {
    try
    {
    using (ServerManager sm = new ServerManager())
    {
    var applicationPool = sm.ApplicationPools[appPoolName];
    applicationPool.ProcessModel.IdentityType = ProcessModelIdentityType.SpecificUser;
    applicationPool.ProcessModel.UserName = appPoolUser;
    applicationPool.ProcessModel.Password = appPoolPass;
    sm.CommitChanges();
    committed = true;
    }
    }
    catch (FileLoadException fle)
    {
    Trace.TraceError(“Trying again because: ” + fle.Message);
    }
    }
    };

    // ServerManager in %WinDir%System32InetSrvMicrosoft.Web.Administration.dll
    var sitename = RoleEnvironment.CurrentRoleInstance.Id + “_Web”;
    var appPoolNames = new ServerManager().Sites[sitename].Applications.Select(app => app.ApplicationPoolName).ToList();
    appPoolNames.ForEach(iis7fix);

  • Pingback: Determining W3SCV name on AZURE | | Windows AzureWindows Azure

  • Karuna

    I used this solution and am facing problems with debugging my application. Any updates on the solution for this problem?

  • Sebastian

    A walkaround for the debugging issue it to start the application without Debugging, make the Identity changes and reattach to the ISS Worker process w3wp.exe

  • Pingback: Windows 8 Preview & Azure Emulator Problems. Hosted Web Core(HWC) es una solución ! - Juanlu, elGuerre

  • Pingback: Windows 8 Preview & Azure Emulator Problems. Hosted Web Core(HWC) es una solución ! « Juanlu, elGuerre

  • SandraG

    What should be the values for apppooluser and apppoolpassword?