ASP.NET allows for Web.Config files at sub-levels within a site structure. However, I can't find any articles discussing how this looks from code.
In the Orchard CMS there are config files all over the shop. There's even a config file in a folder containing only .CSS files! I'm new to larger-scale ASP.NET apps so...
Can someone just tell me if I'm right in my assumptions.
The config file can affect server settings, and hence how a server processes a request to a resource further down a site structure.
From a code point of view, if the same line of code in the same class queries the config file during a request for http://level1.resource then it could read a different value to when the same code executes during a request for http://level1/level2.resource (if there is a web.config at level2)
Overall, the way it works is based on the current request path.
Right?
you can use the multiple web.config files in the sub-folders level. Each folder will contains its own web.config. Multiple Web.config files can't be used at same level.
Below is code for root folder web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<appSettings>
<add key="root" value="This is from root web.config"></add>
<add key="MySetting" value="This my settings is from root web.config"></add>
</appSettings>
</configuration>
and following is code for sub folder web.config.
<?xml version="1.0"?>
<configuration>
<system.web>
</system.web>
<appSettings>
<add key="sub" value="This is from sub web.config settings"></add>
<add key="MySetting" value="This my settings is from sub folder web.config"></add>
</appSettings>
</configuration>
In C# , you can access the settigns of different configuration files as below.
System.Web.Configuration.WebConfigurationManager.AppSettings.Get("Root");
System.Web.Configuration.WebConfigurationManager.AppSettings.Get("MySetting")
This is an old question, but I just asked myself the same one specifically in the Orchard CMS context as per the original post, and I've got an Orchard specific answer.
In the root of Orchard CMS, there's a web.config that want to prevent all users from requesting individual static files. For example, you don't want people to download placement.info or theme.txt from the Theme folders. This is a good "block everything, allow what you need" approach.
<handlers accessPolicy="Script">
<!-- Clear all handlers, prevents executing code file extensions or returning any file contents. -->
<clear />
<!-- Return 404 for all requests via a managed handler. The URL routing handler will substitute the MVC request handler when routes match. -->
<add name="NotFound" path="*" verb="*" type="System.Web.HttpNotFoundHandler" preCondition="integratedMode" requireAccess="Script" />
[...]
</handlers>
The thing is, in subfolders such as Scripts (containing static js files), Styles (containing only lots of static css files), or Content (contains static images for example), you of course want to allow the web browser to request an individual file. So in these subfolders, you have an extra web.config that looks like this:
<handlers accessPolicy="Script,Read">
<!-- For any request to a file exists on disk, return it via native http module. AccessPolicy="Script" above is to allow for a managed 404 page. -->
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" />
</handlers>
PS: I'm currently playing with Themes, and for some reason I've had to add <remove name="StaticFile"/> before each <add name="StaticFile"...> in all these child web.config.
Related
I like to secure all aspx files in a folder ~/Secure/ secure such that specific IP addresses can access the folder's aspx files. I added the following web.config file to the folder, hoping that it adds to the parent web.config:
<configuration>
<system.webServer>
<security>
<ipSecurity allowUnlisted="false">
<clear/>
<add ipAddress="192.168.100.1" />
<add ipAddress="169.254.0.0" subnetMask="255.255.0.0" />
</ipSecurity>
</security>
</system.webServer>
</configuration>
The problem is that I get this error when I try to access to any of the aspx pages in the folder:
This configuration section cannot be used at this path. This happens when the section is locked at a parent level. Locking is either by default (overrideModeDefault="Deny"), or set explicitly by a location tag with overrideMode="Deny" or the legacy allowOverride="false".
What does it take to make this idea happen? I like to just include one web.config file to a folder and that enforces the IP address authorization. I like this idea, since it is no-code and config only.
You cannot do it in the website web.config only.
If you can use IIS manager:
Open IIS Manager, locate the site, click on the folder you want to protect, then click on IP address and Domain Restrinctions.
Also click on "Edit feature settings" in the right Actions panel" to specify actions for unspecified clients (i.e. Deny with Forbidden, or simply Deny With Not Found).
This will generate the right configuration for you.
In your root web.config use the location element:-
<location path="Secure">
<system.webServer>
<security>
<ipSecurity allowUnlisted="false">
<clear/>
<add ipAddress="192.168.100.1" />
<add ipAddress="169.254.0.0" subnetMask="255.255.0.0" />
</ipSecurity>
</security>
</system.webServer>
</location>
My application has this structure
MyApplication
-Themes
In my application's webconfig I remove the UrlAuthorization module and add my own:
<modules runAllManagedModulesForAllRequests="true">
<remove name="UrlAuthorization" />
<add name="MyModule" type="MyType, MyNamespace" preCondition="managedHandler" />
</modules>
My Theme folder has this webconfig (this is the complete webconfig):
<?xml version="1.0"?>
<configuration>
<system.web>
<pages styleSheetTheme="" validateRequest="false" />
</system.web>
</configuration>
I have this deployed in 3 environments. 2 of them works correctly but in one of them I have the UrlAuthorization module working when I make a request do a file inside the Theme folder.
I know that the UrlAuthorization is active because I do not get the resource I requested, but an URL /ReturnURl/... path
The < remove> tag is working because removing it causes the whole request to be redirect to the /ReturnUrl
Is there any reason that may cause this behavior to happen only in this machine?
I deployed all of them and I do not remember making and different task on any of them
thanks!
FYI, it was an issue due to the folders permissions in the file system. I made the environments identical and it worked.
I use a httphandler to remap browser Urls to files in my website. This works fine but I am having trouble accessing files I created under a new directory. The url looks like this:
http://mobile.mysite.com/monitoring/help/help.aspx
Yet the information returned in the 404 error shows it cannot find the file under:
D:\Sites\Website\monitoring\help\help.aspx
Yet the file is really located under:
D:\Sites\Website\mobile\monitoring\help\help.aspx
My http handler normally recognizes the "mobile" subdomain. In fact, if I leave off the actual file and just use the directory, my handler does get called. Even if I put a breakpoint in my code, VS will never get called. Why is IIS accessing the help.aspx under a directory that doesn't exist? Why isn't my httphandler being called. As I mentioned, the httphandler does work for virtually every other file. I am able to call aspx file located under other domains.
This is how my handler looks in the web.config file:
<add name="FileServerHandler-Files" path="*.*" verb="*" type="FileServerHandler" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Either" requireAccess="Read" allowPathInfo="false" preCondition="" responseBufferLimit="4194304" />
Running ASP.NET 4.0 on IIS7
The subdomain "mobile" is actually mapped to the same IP address as the main site. Does this have something to do with it? If it does, it doesn't explain why the handler can access folders under the mobile domain but not aspx files.
While I had an entry in the web.config for the handler to handle directories, I tried moving it up in the list. This worked. Why it stopped working is a mystery as the web.config hasn't changed for a very long time. This is what the entries now look like:
<add name="FileServerHandler-Dir" path="*" verb="*" type="FileServerHandler" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Read" allowPathInfo="false" preCondition="" responseBufferLimit="4194304" />
<add name="FileServerHandler-Files" path="*.*" verb="*" type="FileServerHandler" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Either" requireAccess="Read" allowPathInfo="false" preCondition="" responseBufferLimit="4194304" />
i would like to have my main web.config in the root where it normally is and have another merged in.
Is this possible , i was thinking on placing a another web.config in APP_DATA/CONFIG which will have some additonal stuff that i can update without having to touch the main web.config
I seem to remember that this is possible but i am unsure.. can asp.net dynamically merge these and use both??
Can anyone provide further info?
THanks
No idea what you mean by merge web.config files, but you can have web.config files in subfolders of your ASP.NET application which could override some sections from the root config file (only some sections could be overridden). So for example you could have the following section in your root web.config file:
<appSettings>
<add key="foo" value="bar" />
</appSettings>
and then have a ~/somefolder/web.config which overrides this section:
<appSettings>
<add key="foo" value="baz" />
</appSettings>
and now if inside ~/somefolder/foo.aspx you try to access ConfigurationManager.AppSettings["foo"] you would get baz.
You can use the file= param of the <appSettings> block, if it is only things in there that you need to override.
in web.config:
<configuration>
<appSettings file="relative_path_to_other.config">
<add key="foo" value="bar" />
</appSettings>
</configuration>
and in your other config file you just define the <appSettings> section (not the whole config file)
<appSettings>
<add key="foo" value="baz" />
</appSettings>
I am trying to add
<location inheritInChildApplications="false">
to my parent web application's web.config but it doesn't seem to be working.
My parent's web.config has:
<configuration>
<configSections>
</configSections>
// 10 or so custom config sections like log4net, hibernate,
<connectionStrings>
</connectionStrings>
<appSettings>
</appSettings>
<system.diagnostics>
</system.diagnostics>
<system.web>
<webParts>
</webParts>
<membership>
</membership>
<compilation>
</compilation>
</system.web>
<location ..>
<system.web>
</system.web>
</location>
<system.webServer>
</system.webServer>
My child web application is setup as an application in IIS, and is inheriting from the parent's web.config which is causing problems.
Where exactly should I place the
<location inheritInChildApplications="false">
so it ignores all the various web.config settings?
As the commenters for the previous answer mentioned, you cannot simply add the line...
<location path="." inheritInChildApplications="false">
...just below <configuration>. Instead, you need to wrap the individual web.config sections for which you want to disable inheritance. For example:
<!-- disable inheritance for the connectionStrings section -->
<location path="." inheritInChildApplications="false">
<connectionStrings>
</connectionStrings>
</location>
<!-- leave inheritance enabled for appSettings -->
<appSettings>
</appSettings>
<!-- disable inheritance for the system.web section -->
<location path="." inheritInChildApplications="false">
<system.web>
<webParts>
</webParts>
<membership>
</membership>
<compilation>
</compilation>
</system.web>
</location>
While <clear /> may work for some configuration sections, there are some that instead require a <remove name="..."> directive, and still others don't seem to support either. In these situations, it's probably appropriate to set inheritInChildApplications="false".
It needs to go directly under the root <configuration> node and you need to set a path like this:
<?xml version="1.0"?>
<configuration>
<location path="." inheritInChildApplications="false">
<!-- Stuff that shouldn't be inherited goes in here -->
</location>
</configuration>
A better way to handle configuration inheritance is to use a <clear/> in the child config wherever you don't want to inherit. So if you didn't want to inherit the parent config's connection strings you would do something like this:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<clear/>
<!-- Child config's connection strings -->
</connectionStrings>
</configuration>
I put everything into:
<location path="." inheritInChildApplications="false">
....
</location>
except: <configSections/>, <connectionStrings/> and <runtime/>.
There are some cases when we don't want to inherit some secions from <configSections />, but we can't put <section/> tag into <location/>, so we have to create a <secionGroup /> and put our unwanted sections into that group. Section groups can be later inserted into a location tag.
So we have to change this:
<configSections>
<section name="unwantedSection" />
</configSections>
Into:
<configSections>
<sectionGroup name="myNotInheritedSections">
<section name="unwantedSection" />
</sectionGroup>
</configSections>
<location path="." inheritInChildApplications="false">
<myNotInheritedSections>
<unwantedSection />
</myNotInheritedSections>
</location>
We were getting an error related to this after a recent release of code to one of our development environments. We have an application that is a child of another application. This relationship has been working fine for YEARS until yesterday.
The problem:
We were getting a yellow stack trace error due to duplicate keys being entered. This is because both the web.config for the child and parent applications had this key. But this existed for many years like this without change. Why all of sudden its an issue now?
The solution:
The reason this was never a problem is because the keys AND values were always the same. Yesterday we updated our SQL connection strings to include the Application Name in the connection string. This made the string unique and all of sudden started to fail.
Without doing any research on the exact reason for this, I have to assume that when the child application inherits the parents web.config values, it ignores identical key/value pairs.
We were able to solve it by wrapping the connection string like this
<location path="." inheritInChildApplications="false">
<connectionStrings>
<!-- Updated connection strings go here -->
</connectionStrings>
</location>
Edit: I forgot to mention that I added this in the PARENTS web.config. I didn't have to modify the child's web.config.
Thanks for everyones help on this, saved our butts.
If (as I understand) you're trying to completely block inheritance in the web config of your child application, I suggest you to avoid using the tag in web.config.
Instead create a new apppool and edit the applicationHost.config file (located in %WINDIR%\System32\inetsrv\Config and %WINDIR%\SysWOW64\inetsrv\config).
You just have to find the entry for your apppool and add the attribute enableConfigurationOverride="false" like in the following example:
<add name="MyAppPool" autoStart="true" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated" enableConfigurationOverride="false">
<processModel identityType="NetworkService" />
</add>
This will avoid configuration inheritance in the applications served by MyAppPool.
Matteo
This is microsoft's page on the location tag: http://msdn.microsoft.com/en-us/library/b6x6shw7%28v=vs.100%29.aspx
It may be helpful to some folks.
We're getting errors about duplicate configuration directives on the one of our apps.
After investigation it looks like it's because of this issue.
In brief, our root website is ASP.NET 3.5 (which is 2.0 with specific libraries added), and we have a subapplication that is ASP.NET 4.0.
web.config inheritance causes the ASP.NET 4.0 sub-application to inherit the web.config file of the parent ASP.NET 3.5 application.
However, the ASP.NET 4.0 application's global (or "root") web.config, which resides at C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\web.config and C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config (depending on your bitness), already contains these config sections.
The ASP.NET 4.0 app then tries to merge together the root ASP.NET 4.0 web.config, and the parent web.config (the one for an ASP.NET 3.5 app), and runs into duplicates in the node.
The only solution I've been able to find is to remove the config sections from the parent web.config, and then either
Determine that you didn't need them in your root application, or if you do
Upgrade the parent app to ASP.NET 4.0 (so it gains access to the root web.config's configSections)