The SharePoint Ajax Toolkit now implements the least-trusted principles from Inside WSS I’ve been blogging about. (Get the source from the project site). Here’s some principles and sample code snippets. Feel free to get the full source as a reference implementation.
1. Deployment: Deploy your assembly to the BIN directory which should be running in WSS_Minimal trust– and let WSS manage the trust level based on the CAS policy. Don’t even think about throwing Web Parts in the GAC. Since we’ll need to deploy the feature receiver to the GAC, that will go in a standalone assembly (see point #3). Following is the Assemblies mode from the Solution Manifest:
<Assembly DeploymentTarget="WebApplication" Location="SharePoint.Ajax.dll">
<SafeControl Assembly="SharePoint.Ajax, Version=184.108.40.206, Culture=neutral, PublicKeyToken=5ed42c8fcfe5cf7c"
Namespace="SharePoint.Ajax.WebParts" TypeName="*" Safe="True"/>
<Assembly DeploymentTarget="WebApplication" Location="SharePoint.Ajax.pdb" />
<!– The config DLL contains the Feature Receiver which installs the ASP.NET AJAX configuration. –>
<Assembly DeploymentTarget="GlobalAssemblyCache" Location="SharePoint.Ajax.Config.dll" />
2. CAS policy: Define the minimum CAS permissions you need, and NO MORE. Use the name of the assembly rather than the public key blob, since the blob will assign those permissions to ALL assemblies signed with the key, and we’re shooting for fine-grained permissions. Before defining the CAS policy in teh manifest, define the permissions you need in code as follows. Note that it only needs to execute, run in ASP.NET, and talk to the WSS object model:
[assembly: SharePointPermission(SecurityAction.RequestMinimum, ObjectModel = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution=true)]
Following is my CAS policy. You’ll see how we took the permissions we requested in the assembly and defined them in the CAS policy- no more and no less.
<PermissionSet class="NamedPermissionSet" version="1" Description="Permission set for SharePoint.AJAX">
<IPermission class="AspNetHostingPermission" version="1" Level="Minimal" />
<IPermission class="SecurityPermission" version="1" Flags="Execution" />
<IPermission class="Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, version=220.127.116.11, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
version="1" ObjectModel="True" />
Note that WSS will manage the CAS policy when WSP packages are deployed with the allowCasPolices switch, such as:
stsadm -o deploysolution -name SharePointAjax.wsp -immediate -allcontenturls -allowGacDeployment -allowCasPolicies
However, the customer/ IT admin can choose to manage CAS themselves manually or audit the CAS before deployment. If you’re given a solution with the instructions to deploy with the allowGacDeployment switch, find out WHAT code is being deployed to the GAC. If it’s web part code, JUST SAY NO and send it back to the developer/vendor. You have a right to ask what is going in the GAC, as well as a right to demand an audit of the CAS policy.
3. Compile Feature Receivers independently: don’t mix them in the Web Part assembly. Since Feature Receivers need full trust and GAC deployment, we’ll need to compile these on their own– in this case, SharePoint.Ajax.Config.dll. We use the Feature Receiver to configure the web.config file to enable ASP.NET Ajax (read more about that here– again, thanks to Tony for that idea). To make sure I’m always including the most recently built version and not a previously GAC’d version, I’ll compile this manually using CSC in an MSBuild task. This requires unloading the project from Visual Studio and editing the csproj file, which is really just an MSBuild file. In our case, we’ll want to build that first in the PreBuild target as follows:
<Csc KeyFile="SharePoint.Ajax.snk" EmitDebugInformation="true" OutputAssembly="binSharePoint.Ajax.Config.dll"
Sources="ConfigFeatureReceiver.cs" TargetType="library" Optimize="true"
AdditionalLibPaths="c:PROGRAM FILESCommon FilesMicrosoft Sharedweb server extensions12ISAPI" />
4. Use demands and Link Demands to ensure your code isn’t used to compromise the system. Use Visual Studio Team System for Developers if you have it to perform a code analysis, and pay attention to those security warnings. Throw the attribute [PermissionSet(SecurityAction.Demand)] on classes that override link-demanded classes, and likewise use LinkDemands on methods that expose sensitive operations, as follows: [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)].