Elevated Privilege with SPSite

Here is a code sample of a utility class for elevated privileges using the best practices outlined in my last post.  99% of the time you’ll be able to get the system token using site.SystemAccount.UserToken. However, you may need to elevate privilege if the current user doesn’t have permission to read that object from the SPSite. In this case, you’ll need to elevate privilege just to get the user token– but we don’t want to perform any operations inside RunWithElevatedPrivilege, we only want to get a token out (which is basically a simple byte array). You could also cache the system token in the application if you needed to, although I’m not sure I’d endorse that.

The following static class includes two methods that will reliably run in all security contexts, assuming the assembly has the right CAS permissions. The GetSystemToken method returns a token, while the GetElevatedSite returns an elevated SPSite context. Be sure you wrap these in a using statement to avoid any leaks, and you’re safe to pass in the SPContext.Current.Site object to these methods.

Also, these methods should be used in working with SharePoint’s security, not just to bypass it. Just because you can doesn’t mean that you should, so be sure to practice trustworthy computing practices in your code.  

using System;
using Microsoft.SharePoint;

namespace LitwareSecurity
{
    /// <summary>A class for working with elevated privilege</summary>
    public static class SpSecurityHelper
    {
        /// <summary>Returns an elevated site</summary>
        /// <param name="theSite">
        /// The site that you want an elevated instance of.
        /// You must dispose of this object unless it is part of SPContext.Current.
        /// </param>
        /// <returns>An elevated site context.</returns>
        /// <remarks>Be sure to dispose of objects created from this method.</remarks>
        public static SPSite GetElevatedSite(SPSite theSite)
        {
            var sysToken = GetSystemToken(theSite);
            return new SPSite(theSite.ID, sysToken);
        }

        /// <summary>Gets a UserToken for the system account.</summary>
        /// <param name="site"></param>
        /// <returns>A usertoken for the system account user./returns>
        /// <remarks>Use this token to impersonate the system account</remarks>
        public static SPUserToken GetSystemToken(SPSite site)
        {
            site.CatchAccessDeniedException = false;
            try {
                return site.SystemAccount.UserToken;
            }
            catch (UnauthorizedAccessException) {
                SPUserToken sysToken = null;

                // Only use runwithelevated to grab the system user token.
                SPSecurity.RunWithElevatedPrivileges(
                    delegate()
                    {
                        using (SPSite lolcatKiller = new SPSite(site.ID)) {
                            sysToken = lolcatKiller.SystemAccount.UserToken;
                        }
                    }
                );
                return sysToken;
            }
        }
    }
}

This entry was posted in SharePoint. Bookmark the permalink.

1 Response to Elevated Privilege with SPSite

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s