Summary: AllowPartiallyTrustedCallers is often a necessary assembly attribute if you are developing SharePoint applications. Read about this uncommon but powerful Code Access Security related attribute.
A quick look at the AllowPartiallyTrustedCallers attribute
One can write .NET code for a long time without bumping into the AllowPartiallyTrustedCallers (APTC) assembly-level attribute, but once encountered it is rarely forgotten. My introduction was while writing a Windows SharePoint Services 2003 webpart a few years ago, and I suspect most will encounter this attribute or more specifically the need to use this attribute when writing webparts – either for SharePoint or ASP.NET 2.0.
Background
Microsoft’s .NET Code Access Security (CAS) provides a very powerful and sophisticated set of mechanisms that allow developers and system administrators to control resource access by managed code. For a quick overview of CAS see my forthcoming blog; to access Microsoft’s documentation on CAS start here: CAS . Think of CAS settings as the analog of ACLs/ACEs for code as opposed to users. It’s not a perfect analogy but it’s close enough for present purposes. There are many, many means of limiting or allowing resource access using CAS. The bottom line is that if the code attempting to access a resource does not have the required permission, either inherently or through some external augmentation, an exception will be thrown and the code will not execute and most likely — not even load. Figures 1 and 2 show the permission sets for two different types of assemblies. Those in the My Computer zone, Figure 1, have full trust. Those in the Local Intranet zone, Figure 2, have very restricted permissions, for example Read ony access to only the USERNAME environment variable. CAS works just like ACL/ACE permissions; if not explicitly granted (or inherited) the permission is implicitly denied.
The Global Assembly Cache (GAC)
All assemblies in the GAC have Full Trust by default (the default could be modified by changes to machine.config, but that’s another story for another day). Full Trust means full access to all system resources. A potential security problem exists if code outside the GAC, possessing say limited permissions or sited in a non-trusted location, makes a call into a class contained in a GAC-installed assembly. Potentially malicious code could indirectly gain access to resources. CAS handles this possibility by having all GAC-installed assemblies perform a demand of full trust for all externally calling code. This addresses the security weakness but presents another problem. What if less than fully trusted code requires, legitimately, access to classes located in GAC-installed assemblies? Meet AllowPartiallyTrustedCallers.
The AllowPartiallyTrustedCallers Attribute
Again, this code attribute decorates an assembly only; it cannot be applied to classes, class members or any other program elements. Also, assuming the default security policy has not been tightened up, it only makes sense to use this attribute with assemblies that are intended to be GAC-installed and any other assemblies that would be granted full trust, yet called from less than fully trusted code. An example would be, a class located in a windows services assembly yet called from and ASP.NET assembly. Applying the attribute is straight forward. The class is in the System.Security namespace so either a using(imports) statement or the fully qualified class name is required. Figure 3 shows the attribute being applied. Visual Studio 2005 includes a setting on the property pages of a project that allow you to set this with a checkbox.
Figure 3
Final Notes
Since it is assumed that the assembly decorated with the APTC attribute is itself fully trusted, it must be strong-named. Applying the attribute to an assembly that is not strong-named has no effect.
Using the APTC attribute results in a co-opting of the default security policy defined by the .NET framework. Microsoft included the attribute, reportedly as a last minute inclusion, in 1.0 and has carried it forward since because there are situations that require circumvention of the default policy. Make certain that your APTC decorated assembly does not open any security holes. One of the best ways to do this is to use a LinkDemand. More on that in another blog.
You might be wondering how this might all fit together for your specific situation. Here are a few possible scenarios.
-
Your packaging requires multiple dlls deployed in multiple unsafe locations. You also have a set of classes you want to share and so will be GAC-installed. Apply the APTC attribute to your shared assembly.
-
You need to use .NET framework classes (all of these are GAC installed) from assemblies that are not fully trusted. Create an assembly that can be used as a wrapper for these calls. Apply APTC to that assembly and drop it in the GAC.
-
You have written a SharePoint webpart that uses .NET framework classes. The webpart’s assembly is located in the _app_bin (bin in 2003) folder of the SharePoint virtual directory. You’ll either need to GAC-install the webpart’s assembly or use a solution like the second one here.
Finally, you might be scratching your head, “Wait a minute!” you are saying to yourself. “I have written many ASP.NET applications that call classes in the .NET framework and they work just fine. I have never needed to use APTC.”
At the top of this blog I mentioned that one could write a lot of .NET code without needing to know about APTC. Microsoft applies the APTC attribute to the assemblies listed in the table below. Looking at the list one sees many of the most commonly referenced .NET framework assemblies which explains why you might not have yet run into this attribute, or better said, the requirement for it. Figure 4 shows the ILDASM Manifest for the System.Data.dll assembly; note the APTC attribute.
Accessibility.dll |
System.Web.dll (available only in version 1.1) |
IEExecRemote.dll |
System.Web.Mobile.dll (available only in version 1.1) |
Microsoft.VisualBasic.dll |
System.Web.RegularExpressions.dll (available only in version 1.1) |
Mscorlib.dll |
System.Web.Services.dll |
System.dll |
System.Windows.Forms.dll |
System.Data.dll |
System.XML.dll |
System.Drawing.dll |
|
Figure 4