More on Code Access Security

Posted Tuesday, August 28, 2007 3:47 PM by C-Dog's .NET Tip of the Day

I had promised an update to my Code Access Security post, so here it is. Hopefully, by now you have stopped being a cowboy and got your DLL out of the GAC and put the trust level back to minimal. If not, it is time. Here is some more info. Not just web parts require CAS. If you have any custom application pages or web user controls, more than likely they are going to require some CAS to work right. If anything the AspNetHostingPermission will be required for most things.

First I recommend, creating a SharePoint solution for everything (whether they are web parts or not). Follow the instructions in the last post to create a cab.ddf and Manifest.xml file. Put these in a folder called Solution (or whatever) in every single project you build. In my next post, I will explain how to add an msbuild target to create the wsp file everytime you compile.

I found that not all things were necessary in my last post but they do not hurt. Regarding lines like these in AssemblyInfo.cs.

assembly: AspNetHostingPermission(SecurityAction.RequestMinimum)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum,
Execution = true)]
[assembly: SharePointPermission(SecurityAction.RequestMinimum, ObjectModel = true, 
Impersonate = true, UnsafeSaveOnGet = true, Unrestricted=true)]

For the most part you can skip these. This just tells the assembly to not load if it hasn't already been granted permission to run. So if you dont want to add them, don't bother. However, you still do need AllowPartiallyTrustedCallers().

Sometimes when you set up a solution and you think everything is correct, your code still will give you permissions errors. Now I can tell you what installing the solution does behind the scenes so that you can check the system files and make sure everything made it in there correctly. First, it takes a copy of your web.config and makes a backup copy using a timestamp. It then modified the web.config to include any SafeControl elements you specified in the manfiest file. It also modifies the custom trust configuration file path. This is because it makes a copy of the minmal trust configuration file and makes a backup of it. You'll see a node entry similar to the following.

<trustlevel name="WSS_Custom" policyFile="C:\Program Files\Common Files\Microsoft Shared\Web Server 
Extensions\12\config\wss_custom_wss_minimaltrust_5391d4d8-0991-4de1-b033-bc03de8f0bab.config" />

Be aware of this change when making changes to your web.config. Don't ever just overwrite it with whatever you have in source control because it will end up pointing to the wrong configuration file and none of your CAS will work any more.

If you examine the trust configuration file, you will find a permission set with the same name specified in your manifest file similar to the following (not necessarily the same permissions).

<PermissionSet class="NamedPermissionSet" version="1" Description="Permission set for MyAssembly." Name="MyAssembly.wsp-eff41d49-7420-4f02-a884-e67752a447f0-1">
  <IPermission class="AspNetHostingPermission" version="1" Level="Minimal" />
  <IPermission class="SecurityPermission" version="1" 
Flags="Execution,ControlPrincipal,ControlAppDomain,ControlDomainPolicy,ControlEvidence" />
  <IPermission class="Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, 
Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" version="1" ObjectModel="True"/>
  <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, 
PublicKeyToken=b77a5c561934e089" version="1" Flags="ControlThread, Execution" />
  <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.0.0, 
Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Read="UserName" />
  <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, 
PublicKeyToken=b77a5c561934e089" version="1" Read="$AppDir$" Write="$AppDir$" Append="$AppDir$" PathDiscovery="$AppDir$" />
  <IPermission class="SqlClientPermission" version="1" Unrestricted="true" />
</PermissionSet>

You will also find a code group with the name of your permission set. Basically it is the name of your solution file plus some guid. This code group lists the path to your DLL.

<CodeGroup class="UnionCodeGroup" version="1" 
PermissionSetName="myassembly.wsp-eff41d49-7420-4f02-a884-e67752a447f0-1">
  <IMembershipCondition version="1" Name="MyAssembly" class="UrlMembershipCondition" Url="$AppDirUrl$/bin/MyAssembly.dll" />
</CodeGroup>

That is all that really happens behind the scenes when you install CAS via a WSP solution file. If you look in your conifguration file and you don't find your DLL listed in there, you know its not going to work. If the configuration looks good, double check the path in the web.config and make sure it is still loading the right configuration file. If not, a redeployment of all your solutions should fix it.

Read the complete post at http://www.dotnettipoftheday.com/blog.aspx?id=381