Using ASPNet_Regiis to encrypt custom configuration section - can you do it? - asp.net

I have a web application with a custom configuration section. That section contains information I'ld like to encrypt (was hoping to use ASPNet_RegIIS rather than do it myself).
Web.Config:
<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<configSections>
<section name="MyCustomSection"
type="MyNamespace.MyCustomSectionHandler, MyAssembly"/>
</configSections>
<configProtectedData>
<providers>
<clear />
<add name="DataProtectionConfigurationProvider"
type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a,
processorArchitecture=MSIL"
keyContainerName="MyKeyContainer"
useMachineContainer="true" />
</providers>
</configProtectedData>
<MyCustomSection>
<blah name="blah1">
<blahChild name="blah1Child1" />
</blah>
</MyCustomSection>
The configuration handler works great before trying to encrypt it. When I try to encrypt it with:
aspnet_regiis -pef "MyCustomSection"
c:\inetpub\wwwroot\MyWebsite -prov
DataProtectionConfigurationProvider
I get an error:
Encrypting configuration section... An
error occurred creating the
configuration section handler for
MyCustomSection: Could not load file
or assembly 'MyAssembly' or one of its
dependencies. The system cannot find
the file specified.
(c:\inetpub\wwwroot\MyWebsite\web.config
line 5)
I have tried with/without the provider configured. With/without section groups. With/Without having started the website before hand. I've tried temporarily putting my assembly in the GAC for the registration. I also tried my log4net section just to try something that wasn't mine, with no luck. I've run the command prompt as Administrator. Any ideas? Or can ASPNet_RegIIS just not be used for custom sections?
One final shot after viewing MSDN was changing my handler to inherit from ConfigurationSection rather than implementing IConfigurationSectionHandler since it was technically deprecated in 2.0 (hoping it was something regarding aspnet_regiis version). No luck there either.
Any ideas let me know. Thanks!

aspnet_regiis must be able to bind the assembly. The normal .net binding rules apply.
I get around this by creating directory called aspnet_regiis_bin in the same directory as aspnet_regiis.exe and an aspnet_regiis.exe.config file with aspnet_regiis_bin as a private path like this:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="aspnet_regiis_bin"/>
</assemblyBinding>
</runtime>
</configuration>
I then copy the assemblies that define the custom configuration sections into aspnet_regiis_bin so that aspnet_regiis can find them.
This procedure doesn't require the assemblies to be strong named or in the GAC but does require messing around in the framework directories.

I am using a workaround whereby I temporarly comment out the contents of the configSections element:
<configSection>
<!--
<section name="CustomSection" type="" />
-->
</configSection>
You can then run the encryption using aspnet_regiis -pef as usual. After this has run just uncomment the section and your site is ready to run.

This is a total hack, but I'm not sure that there's another way to do it without strongly naming the assembly that defines your custom section and GACifying it (although you mentioned that didn't work, either, and I'm not sure why it wouldn't). Since aspnet_regiis runs in the < drive >:\Windows\Microsoft.Net\Framework\< version > folder (in WinXP), you can copy the DLL that defines your config section into the relevant Framework\< version > folder, and then it should work.

For the record, I ended up with a little maintenance page to do this for me.
var currentConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~/");
// Unprotect
ConfigurationSection section = currentConfig.GetSection("MyCustomSection");
if (section.SectionInformation.IsProtected)
{
section.SectionInformation.UnprotectSection();
currentConfig.Save();
}
// Protect
if (!section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
currentConfig.Save();
}
Caveats: Your process will need write access to the config files being modified. You'll want some way to authorize who can run this. You'll generally restart the website when you Save.

The answer that is shown as correct is correct. I wanted to add a comment but could not because this is too long of a comment (sample config entries).
The section name should use the full name of the assemblies. A runtime assembly qualification does not work with aspnet_regiis.exe.
This WORKS:
<configSections>
<section name="securityConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Security.Configuration.SecuritySettings, Microsoft.Practices.EnterpriseLibrary.Security, Version=5.0.414.0, Culture=neutral, PublicKeyToken=9c844884b2afcb9e" />
</configSections>
But this DOESN'T WORK:
<configSections>
<section name="securityConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Security.Configuration.SecuritySettings, Microsoft.Practices.EnterpriseLibrary.Security" />
</configSections>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Security" fullName="Microsoft.Practices.EnterpriseLibrary.Security, Version=5.0.414.0, Culture=neutral, PublicKeyToken=9c844884b2afcb9e" />
</assemblyBinding>
</runtime>

Related

How to use ASP.NET 4.8 ConfigBuilders with system.serviceModel section of web.config

I have an ASP.NET 4.8 app that I am trying to integrate configuration builders into. I have installed the NuGet package Microsoft.Configuration.ConfigurationBuilders.Environment and added the required sections to Web.config (heavily truncated here).
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="configBuilders" type="System.Configuration.ConfigurationBuildersSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" restartOnExternalChanges="false" requirePermission="false"/>
</configSections>
<configBuilders>
<builders>
<add name="EnvironmentExpand" mode="Expand" type="Microsoft.Configuration.ConfigurationBuilders.EnvironmentConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.Environment" />
</builders>
</configBuilders>
<system.serviceModel configBuilders="EnvironmentExpand">
....
</system.serviceModel>
</configuration>
When I run the application I get an HTTP 500 response from every action, with the message Unrecognized attribute 'configBuilders'. Intellisense in Visual Studio also highlights configBuilders and says The configBuilders attribute is not allowed.
If I remove the configBuilders attribute from system.serviceModel the application runs correctly although of course none of the placeholders in that section are expanded.
If I remove the configBuilders attribute from system.serviceModel and add it to another section, for instance connectionStrings, the application runs and the placeholders in the connectionStrings section are replaced.
Clearly there's something different about the system.serviceModel section but I don't understand what or how I can work around it so that I can replace placeholders in there.
If you look at your machine.config, you'll see that system.serviceModel is a sectionGroup and not a section. ConfigurationBuilders only apply at the section level. WCF and ASP.Net for better or worse have their large configuration divided into multiple sections.

Avoid inherited ELMAH errors in an ASP.NET subapplication

I have a parent IIS application that uses ELMAH and a child ASP.NET application (virtual directory) that doesn't use ELMAH. When I try to browse my subapplication I get this error:
Could not load file or assembly 'Elmah' or one of its dependencies. The system cannot find the file specified.
Which is understandable as my child application's bin folder doesn't contain any ELMAH assemblies.
The problem probably is that the parent web.config file contains this:
<configSections>
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
<section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
<section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
</sectionGroup>
</configSections>
As far as I understand there is no way to stop <configSections> inheritance, see e.g. How to stop inheritance of <configSections>in Web.Config. Is there a way to run my ELMAH-free subapplication then?
You cannot keep your subapplication ELMAH-free because of the parent configuration. However - since I imagine you don't want to reference the assemblies from the parent - what you can do is tell your subapplication to look for assemblies in the parent bin folder with the probing configuration.
This way your subapplication doesn't need to know what assemblies exist for the parent, only that if an unknown assembly is needed it can be found in the parent folders
Edit: That's indeed a bummer. Clearing and removing configsections tags was considered too complex by Microsoft :
<clear /> and <remove /> were never implemented for configSections and sectionGroups because of the difficulty involved attempting to merge different definitions of the same section-handlers and section groups.
Hence the path workaround. You could also set up the applications so they are not related in terms of hierarchy, if this is critical
I have found that adding enableConfigurationOverride="false" to the application pool definition fixes this problem.
From the MSDN docs:
Optional Boolean attribute. When true, indicates that delegated settings in Web.config files will processed for applications within this application pool. When false, all settings in Web.config files will be ignored for this application pool.The default value is true.
There are two methods of doing this, where ChildApplicationName should be replaced with the value of your application pool name.
Method 1 (preferred/advised):
Execute the following command in appcmd in Administrator mode:
appcmd.exe set config -section:system.applicationHost/applicationPools /[name='ChildApplicationName'].enableConfigurationOverride:"False" /commit:apphost
Method 2:
The second involves directly editing the %windir%\System32\inetsrv\config\applicationHost.config file allows the application to effectively ignore the parent application. For various reasons, I don't advice doing this, but I leave this here for posterity.
In order to set this, do a search for your child application pool name. It should be under the xpath. /configuration/system.applicationHost/applicationPools.
<configuration>
<system.applicationHost>
<applicationPools>
...
<add name="ChildApplicationName" enableConfigurationOverride="false" />
...
<applicationPools>
<system.applicationHost>
<configuration>

Server Error in '/' Application. This type of page is not served

I have an host where I hosted a webpage with .cshtml extension. My host is arvixe.com that provides ASP and .NET hosting but when I try to load my web page I get this error message.
Server Error in '/' Application.
This type of page is not served.
Description: The type of page you have requested is not served because it has been explicitly forbidden. The extension '.cshtml' may be incorrect. Please review the URL below and make sure that it is spelled correctly.
Requested URL: /samples/WoT/Default.cshtml
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.276
I read something does I have to write something in my web.config file to make it work
like this
<compilation>
<assemblies>
<add assembly="System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</assemblies>
<buildProviders>
<add extension=".cshtml" type="System.Web.WebPages.Razor.RazorBuildProvider, System.Web.WebPages.Razor"/>
</buildProviders>
</compilation>
But I tried everything, paste it in on different lines, nothing worked. What do I miss or do wrong?
I believe you are not making using the MVC feature and trying to load just the razor view outside views or custom Area folders.
Then you need to enable webpages key in Web.config which is disabled by default in .Net 4.0
<add key="webpages:Enabled" value="true" />
<appSettings>
<add key="webpages:Enabled" value="true" />
Repairing this in Windows 10 Pro using IIS 10 was a nightmare, it took two days but I was finally able to achieve the desired results using the following procedure:
Open your web site in Visual Studio. The way you do this is to go to File > New > Web Site and then select ASP.Net Empty Web Site AND before you click OK change the location to your project location. In my case I had my project in C:\inetpub\wwwroot\AspNet\Projects\Test
Open internet information services manager (click the "cortana" search and type IIS, it should show up as long as you have it installed). Locate your project folder under the ServerName > Sites > Default Web Site > ... , right click on it and click the "Convert to web Application" button. Accepting the defaults at the prompt by clicking OK should be sufficient in most cases.
Use the following Web.Config file, or something similar. NuGet may overwrite some settings but this isn't a big problem.
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=301879
-->
<configuration>
<appSettings>
<add key="webPages:Version" value="3.0.0"/>
<add key="webpages:Enabled" value="true"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
</assemblyBinding>
</runtime>
</configuration>
Delete your bin folder, and packages.config file, if they exist. This is because we must assume that something in that bin folder is corrupt since IIS is designed to run Razor/ASP. In your visual studio project you will need to refresh your project so it knows these files have been deleted. This can be done by clicking the refresh button in the menu on the top of the Solution Explorer frame. In you visual studio project go to Tools > NuGet Package Manager > Package Manager Console and enter the following two commands.
Install-Package Microsoft.AspNet.Razor -Version 3.0.0
Install-Package Microsoft.AspNet.WebPages
This was enough to get *.cshtml pages to be rendered by IIS 10 on Windows 10 Pro.

Meleze.web asp.net mvc 3 razor minify and compress html

I have find meleze.web in nuget to remove extra white spaces in generated html result.
but when i set web.config new , and run nothing happend to result.
is there any correct sample or special configs ?
<configuration>
<system.web.webPages.razor>
<host factoryType="Meleze.Web.Razor.MinifyHtmlWebRazorHostFactory,Meleze.Web.Razor" />
</system.web.webPages.razor>
</configuration>
For a little bit of context, we're talking about the tool described here: http://cestdumeleze.net/blog/2011/minifying-the-html-with-asp-net-mvc-and-razor/
I used the following config:
<configuration>
...
<system.web.webPages.razor>
<host factoryType="Meleze.Web.Razor.MinifyHtmlWebRazorHostFactory, Meleze.Web, Version=1.0.0.1, Culture=neutral, PublicKeyToken=0a868b5321967eda" />
...
Maybe you have changed the /web.config instead of the /Views/web.config that config.
Contact the package owner if needed to get help ;-)

asp.net, url rewrite module and web.config

i'm using ASP.net with .NET 3.5 on IIS7 (Vista) with the URL Rewrite Module from Microsoft.
This means, that i have a
<system.webServer>
<rewrite>...</rewrite>
...
</system.webServer>
section within the web.config, but i get a warning, that within the system.webServer the element "rewrite" is not allowed.
How can i configure my system to allow (and maybe even have Intellisense) on the rewrite-part of the web.config?
Thank you
Christoph
I was able to get this working in Visual Studio 2010.
Start with Ruslan's post here and download the 2.0 IntelliSense file. Then, just follow the directions he posted previously here. All I ended up doing was running the following command as Ruslan instructs:
C:\download_directory\rewrite2_intellisense>cscript UpdateSchemaCache.js
As Christoph points out in his comment, make sure you replace VS90COMNTOOLS with VS100COMNTOOLS in UpdateSchemaCache.js before running the above command if you are using Visual Studio 2010.
I did not need to restart Visual Studio. I added the <rewrite> section only to the applicable Web.config transformation files, as having it in the main Web.config breaks local debugging.
I believe you need to have the URL Rewrite Module "installed" within the web.config file on your system.
You either need to install the module on your application via the IIS 7.0 interface or have your hosting firm do it for you.
I believe you need to define the module in your web.config like this:
<system.webServer>
<modules>
<add name="UrlRewriteModule" type="UrlRewritingNet.Web.UrlRewriteModule, UrlRewritingNet.UrlRewriter" />
</modules>
</system.webServer>
Update: Intellisense can be setup here:
http://ruslany.net/2009/08/visual-studio-xml-intellisense-for-url-rewrite-1-1/
Update: Verify that the sectionGroup is identified in %systemroot%\system32\inetsrv\config\applicationHost.config:
<sectionGroup name="rewrite">
<section name="rules" overrideModeDefault="Allow" />
<section name="globalRules" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
<section name="rewriteMaps" overrideModeDefault="Allow" />
</sectionGroup>

Resources