With regard to your second question about how to ensure that configuration changes are persisted to a site's web.config
rather than applicationHost.config
, this can be controlled via Feature Delegation.
If you navigate to the machine node of IIS Manager you will see an icon named "Feature Delegation":
Launch this IIS "applet" and you will be presented with a list of features that can have their configuration delegated to web.config
.
Settings that are marked Read/Write will usually have their settings written to the web.config
file. Settings that are marked Read Only will usually have their settings written to applicationHost.config
and cannot be overridden in the web.config
file.
As it so happens the <windowsAuthentication>
configuration can be delegated to the web.config
file.
Minor Gotcha:
Not all of the applets surface the full range of settings you can configure. A good example of this as it so happens is the <windowsAuthentication>
useAppPoolCredentials
attribute. It's no-where to be seen in the Authentication applet, not even under Advanced Settings.
However you can get at this value (and pretty much everything else) via the Configuration Editor. If you navigate to your web site's node in the left hand pane in IIS manager you will see this icon under Management:
If you launch the Configuration Editor you'll be presented with a dropdown list containing a tree of various settings:
If we select the /system.webServer/security/authentication/windowsAuthentication
node we are presented with the full spectrum of settings that can be changed. Here we can see the setting we're interested in (useAppPoolCredentials
):
You can choose whether to configure the values for the website in web.config
or in applicationHost.config
from the From: drop down list next to the config section tree drop down:
If a section has not been delegated as Read/Write in the web.config
then you'll see the following:
We get an alert saying that this particular feature is locked, all of the settings are greyed out and disabled and there's a padlock indicating that child settings of this feature are also locked out.
Finally, not all settings can be delegated, for example site bindings, application pool, virtual directories.
ASP.NET does not support having multiple built-in authentication modules at once. This is prominent in the documentation, <authentication mode="[Windows|Forms|Passport|None]" ...>
Solutions:
- Build a custom IHttpModule which handles authentication.
- Separate your application into two web applications in your IIS, which point towards two different directories with different configuration files. This is the easiest solution.
- Separate your application into two web applications in your IIS, but point both of them to the same directory. You will need to remove the authentication- and impersonation settings from the web.config residing in the directory, and move these into the system-wide web.config (%SystemRoot%\Microsoft.NET\Framework64\v4.0.30319\Config\web.config or similar). These settings must be wrapped by location-tags using the name of the IIS-site.
Example:
<location path="My Awesome Site - Forms">
<system.web>
<authentication mode="Forms" />
</system.web>
</location>
<location path="My Awesome Site - Windows">
<system.web>
<authentication mode="Windows" />
<identity impersonate="true"/>
</system.web>
</location>
Best Answer
Yes. I've served the exact same code/files from multiple AppPools for years; it works fine.
But all instances will read web.config identically since Microsoft's standard functionality wasn't written to do what you're trying to do. So you will have to implement your own custom solution for determining what instance the code is running under and choose the appropriate configuration variables based on that. You could either store your config data in a custom config section within web.config (defined in "configSections") or have a separate .config file somewhere else.
What I usually do is switch the code's behavior based on the path to the IIS Application it's running under (i.e. the path). E.g. if the site is being served up under "/example1", I pick one set of config data, and if it's served up under "/example2" it gets another set. (Note that you'll also want to handle the config for the Dev Server's URL when you're running your site through VisualStudio.)