Tip #20 – Opting Out of Security Changes in .NET 4 in ASP.NET and Custom AppDomains
March 2nd 2010
Legacy CAS Policy in ASP.NET
In a previous tip I discussed how you could re-enable CAS policy in applications running in .NET 4 by adding a switch to the application configuration file. However, Constantin Baciu brought up that even when using this configuration switch in a web.config, ASP.NET still threw the SecurityException:
This method explicitly uses CAS policy, which has been obsoleted by the .NET Framework. In order to enable CAS policy for compatibility reasons, please use the NetFx40_LegacySecurityPolicy configuration switch. Please see http://go.microsoft.com/fwlink/?LinkID=155570 for more information.
Definitely a confusing error message, since you already added the NetFx40_LegacySecurityPolicy configuration switch. The problem is that in order for this switch to actually work, it must be in the executable’s application configuration file. Putting in the web.config has no effect; the switch must be in the configuration file for the server executable, like IIS or Visual Studio’s local web server. Since just about all web hosts I know of won’t let you modify the configuration file for the server, we need a different option.
Fortunately, ASP.NET does support enabling CAS policy in .NET 4, but it’s with a different switch in the web.config. Enter the new legacyCasModel attribute of the trust element. This is the same element that allows you to configure the trust level of the application.
<trust legacyCasModel="true"/>
This enables you to get past the SecurityException above, but keep the following things in mind:
- You will be using the legacy security configurations from .NET 3.5 when using ASP.NET. These permission sets are kept in the runtime directory’s Config folder and have names like legacy.web_mediumtrust.config and legacy.web_minimaltrust.config.
- Security asserts are no longer required when only full trust code is on the call stack. This is because ASP.NET will still set up a fully trusted AppDomain, because it relies on CAS Policy to apply specific permissions to assemblies. In .NET 4 ASP.NET sets up a sandbox AppDomain by default, which means that even if only fully trusted code is on the call stack, as soon as a permission demand occurs, the stack walk will fail once it hits the AppDomain boundary.
- Of course, CAS Policy is now enabled, which means the machine’s policy configuration affects what permissions an assembly has.
Legacy CAS Policy at the AppDomain Level
When you specify the legacyCasModel attribute in the web.config, ASP.NET uses that information to set up an AppDomain that has legacy CAS policy enabled. The good news is that by using some lower-level APIs, you can do the same thing.
You may ask "why would you want to do this?" One scenario I can think of is for an existing application that uses AppDomains to isolate other pieces of code (e.g. for add-ins), but some of these old pieces of code use the older security APIs that are obsolete in .NET 4.
The key API is AppDomainSetup.SetCompatibilitySwitches; remember that when setting up an AppDomain you can optionally use an instance of the AppDomainSetup class to initialize the AppDomain. The code example below shows how this is done.
C#
var setup = new AppDomainSetup
{
ApplicationBase = Environment.CurrentDirectory
};
setup.SetCompatibilitySwitches(new[] { "NetFx40_LegacySecurityPolicy" });
AppDomain casPolicyEnabledDomain = AppDomain.CreateDomain("CAS Policy Enabled Domain", null, setup);
VB
Dim setup = New AppDomainSetup With {.ApplicationBase = Environment.CurrentDirectory}
setup.SetCompatibilitySwitches(New String() {"NetFx40_LegacySecurityPolicy"})
Dim casPolicyEnabledDomain As AppDomain = AppDomain.CreateDomain("CAS Policy Enabled Domain", Nothing, setup)
And that’s all there is to it.
Syndication