Working easier with custom CAS policies

Security Exception while trying to execute a custom Web Part with insufficient permissions
Working with custom CAS policies is not trivial. Many developers find it challenging to figure out what permissions their code should have, so instead deploying safely to Web Application (BIN) they choose to deploy their assemblies to the Global Assembly Cache (GAC) granting their code full trust. There is however one trick that makes it very easy to find out what permissions you should grant to your code. Find out how to craft your custom CAS policies the easy way.

CAS 101

CAS policies have been around for a while now. They have nothing to do with SharePoint: CAS is a part of the .NET platform and allows you to run custom code securely. The whole idea behind CAS is that custom code should have only those permissions that it requires to run: no more no less. By granting your code specific permissions, as opposite to running it with full trust, you can minimize the chance for breaking into your code and the impact of it should someone succeed. And although it sounds logical to use CAS, many developers don’t. Many developers find it difficult and too time consuming to try to understand what their code does exactly, how it works, and which permissions it requires. As a result they choose for the less secure approach and deploy their assemblies to GAC.

Secure code and SharePoint 2010 = Sandboxed Solutions

SharePoint 2010 provides a new ability of executing code in a secure manner called Sandboxed Solutions. The SharePoint 2010 Sandbox allows you to execute custom code in an isolated and secure manner. Under the hood Sandbox itself is limited by a custom CAS policy that makes it possible to run custom code securely. The really great thing about working with Sandboxed Solutions is, that as a developer, you don’t have to do any additional work to make your code work. All you have to take care of is to be sure that the API that you are using is supported in Sandboxed Solutions.

Unfortunately there is a downside to building Sandboxed Solutions at this moment. The API supported in the Sandbox is limited what means that certain things simply cannot be achieved using Sandboxed Solutions. This is especially true when building WCM solutions which use the Microsoft.SharePoint.Publishing namespace that is not available in Sandbox. In all those scenarios you have two choices: look away and deploy everything to GAC under full trust or do things the right way and create a CAS policy for your custom code. And although it might seem a tedious process, it isn’t. In fact using a simple trick you can find exactly which permissions are missing and should be granted to your code. Find out how to do it.

Important! Before you start

Depending on what your solution does, you might need the basic permissions to allow your code to run. Whenever you’re making use of the SharePoint API in your code, you have to grant it the permission to use the SharePoint Object Model. Without this, you will get a Security Exception and you won’t be even able to debug your code. To make it easier for you I created a template for a basic CAS policy that allows you to use the SharePoint API. This template is a great starting point for adding additional permissions required by your code.

Finding out required permissions

To illustrate working with custom CAS policies we will create a custom Web Part which retrieves information about navigation nodes from the Navigation Provider. The Web Part retrieves the Root Node and displays its Title.

[ToolboxItemAttribute(false)]
public class WebPart1 : WebPart {  
    protected override void OnInit(EventArgs e) {
        base.OnInit(e);
        EnsureChildControls();
    }

    protected override void CreateChildControls() {
        base.CreateChildControls();

        SiteMapNode node = PortalSiteMapProvider.CurrentNavSiteMapProvider.RootNode;
        Controls.Add(new Literal {
            Text = node.Title
        });
    }
}

The challenge

As you might have expected after deploying this Web Part without providing any CAS policies other than the standard template I mentioned before, we will get an exception:

Exception displayed after trying to open the Web Part

By viewing the exception we can see that it’s a FileIOPermission that we’re getting. Unfortunately we cannot really tell what file the Navigation Provider is trying to access or what operation it is trying to do on the file (eg. read, write or both). Using the information from the stack trace you could disassemble the specific assembly and try to read the code to figure out what the code is trying to do, but this can get quite time consuming. This is exactly when most developers decide to flip the switch and use GAC deployment instead.

The Trick

If you want to know what permission you are exactly missing, all you have to do, is to wrap the code in a try..catch block and catch the SecurityException exception:

protected override void CreateChildControls() {  
    base.CreateChildControls();

    try {
        SiteMapNode node = PortalSiteMapProvider.CurrentNavSiteMapProvider.RootNode;
        Controls.Add(new Literal {
            Text = node.Title
        });
    }
    catch (SecurityException ex) {
        throw;
    }
}

After you redeploy the Web Part, attach the debugger to the w3wp process of your Web Application’s Application Pool and set a breakpoint on the throw; line.

Breakpoint set in the catch block

When you refresh your page the breakpoint will be hit and you will be redirected to Visual Studio. To see which permission you are missing exactly QuickWatch the exception caught in the ex variable and zoom in on the m_demanded field which will contain the exact permission that you can copy & paste into your custom CAS policy.

Missing permission information displayed in the exception QuickWatch window

Tip: Whenever you get a FileIOPermission exception pointing to a file located somewhere within your Web Application’s IIS directory (inetpub) you can use the $AppDir$ alias instead the path specified in the exception. This will make your CAS policy more flexible as the locations of the inetpub directory may be different on different environments.

After adding the missing permission, our Web Part should work as intended.

Custom Web Part showing the title of the Root Navigation Node after adding the FileIOPermission to the custom CAS policy

Summary

SharePoint 2010 provides you with a number of approaches to run custom code securely. Sandboxed Solutions, which are the preferred approach, have unfortunately some API limitations why in some scenarios you could be forced to use deployment to Web Application with custom CAS policies. By catching SecurityException in your code you can easily figure out which permissions your custom code exactly requires what allows you to be productive and deploy your code securely.

Technorati Tags: SharePoint 2010

Comments

comments powered by Disqus