SharePoint Security “Do As System User”
Scenario
You are writing a custom web part or control and want to be able to access a list or resource within your code that the current user otherwise does not have permissions to. For me, this happens quite frequently. For example:
- Reading info from a list dedicated to storing Application Settings that only an administrator can read and edit
- Modifying permissions on a list item after creating it
- Modifying a list item other than the specific item in context
- Updating Web properties
- Kicking off a workflow from code as a result of a users action (event handlers are also a good place to do this, which already run under the context of the System user)
What Didn’t Work
SPSecurity.RunWithElevatedPriveleges - this only impersonates the user account running the thread in order to access network resources, etc. But if you are accessing SharePoint resources using the SPContext.Current.Web, your SPWeb object is still limited to the permission set of the original user initiating the request.
What Did Work
Create a new site using the Site.SystemAccount UserToken and then open the web using this Site. Here are two helper methods I am using for doing just this:
public delegate void SPWebAction(SPWeb web); public static void DoAsSystemUser(SPWeb web, SPWebAction action) { SPUser systemUser = web.Site.SystemAccount; DoAsUser(web, systemUser, action); } public static void DoAsUser(SPWeb web, SPUser user, SPWebAction action) { // If we are already running as the given User Token, just pass the web along if (web.CurrentUser != null && web.CurrentUser.UserToken.CompareUser(user.UserToken)) { action(web); return; } using (SPSite site = new SPSite(web.Site.ID, user.UserToken)) { using (SPWeb userWeb = site.OpenWeb(web.ID)) { action(userWeb); } } }
Two more things that still need to be addressed are Security Validation and Unsafe Updates, which I will talk about in the next post.