Search This Blog

Tuesday, December 14, 2010

SharePoint Elevated Privilege without RunWithElevatedPrivelege

ou 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.
Best Practices for Elevated Privilege in SharePoint:
Elevated Privilege can be used to bypass or work with security, and can be performed either through SPSecurity or through impersonation techniques involving the SPUserToken and the SPSite class. It's one of the most misunderstood aspects of the SharePoint API, but in general you should always prefer impersonation using the SPSite class and SPUserToken objects. Here's my list of best practices for elevated privilege code in SharePoint that will help you create more reliable applications for the enterprise.
• Avoid using SPSecurity.RunwithElevatedPrivilege to access the SharePoint object model. Instead, use the SPUserToken to impersonate with SPSite.
• If you do use SPSecurity.RunwithElevatedPrivilege, dispose of all objects in the delegate. Do not pass SharePoint objects out of the RunwithElevatedPrivilege method.
• Only use SPSecurity.RunwithElevatedPrivilege to make network calls under the application pool identity. Don't use it for elevation of privilege of SharePoint objects.
• Always use the SPSite constructor with an SPUserToken to create an elevated privilege security context in SharePoint. To impersonate the system, use the SystemAccount.UserToken property of the current SPSite context, such as:
var site = new SPSite(SPContext.Current.Site.ID, SPContext.Current.Site.SystemAccount.UserToken);
• Avoid passing SharePoint objects between different security contexts (SPSite instances), with the exception of the SPUserToken used in the SPSite ctor. An SPUser object created from SPSite A cannot (reliably) be passed to SPSite B. This can be the source of obscure bugs in production that are difficult to reproduce in development. For example, an SPUser reference created from SPContext.Current.Site cannot reliably be used in an elevated site context, as the user reference may take on a different meaning in the alternate context.
• Never use elevated privilege to bypass security-- always use it to work with security.
• Restrict what assemblies can use elevated privilege by running in minimal trust, avoiding the GAC, and auditing any CAS policies deployed with vendor solutions.
A better way to do perform system actions is to impersonate the SHAREPOINT\system account. Impersonation is a concept that is built into the object model, but is underutilized by developers.
The SPSite object takes an SPUserToken object in its constructor in order to support impersonation. (This does require Impersonate="True" for the Microsoft.SharePoint.Security.SharePointPermission permission class). You can impersonate any user when creating the SPSite context-- so to get the system account, just use the magic system account "SHAREPOINT\system".
Here's a code sample of SYSTEM ACCOUNT impersonation. The SYSTEM ACCOUNT uses the login name "SHAREPOINT\system" internally while it will use the process identity (usually that means the application pool identity, but it could be the service identity if a task was run as a timer job) when making external network calls. Note that the account is abstracted, and when a request comes into the system AS this account it will take on the identity of SYSTEM ACCOUNT.
Here's the code sample. Grab a user object, and then grab the SPUserToken for impersonation:
var user = SPContext.Current.Web.AllUsers[@"SHAREPOINT\SYSTEM"];
var superToken = user.UserToken;
using (var site = new SPSite(SPContext.Current.Web.Url, superToken))
{
// This code runs under the security context of the SHAREPOINT\system
// for all objects accessed through the "site" reference. Note that it's a
// different reference than SPContext.Current.Site.
using(var elevatedWeb = site.OpenWeb())
{
// Perform actions as SYSTEM here
}
}

Because the thread identity hasn't changed, this will produce more stable code in most circumstances, although you should be aware that ONLY objects that are referenced from the elevated site context will run as system.
Write your comment now

*Email:      *Password:  
Don't have SiliconIndia account? Sign up    Forgot your password? Reset

   Cancel
soumya dasari's latest postings
In SharePoint 2003 (WSSv2) with FrontPage, it was so easy to edit a page. Just open the page you want to edit in Internet Explorer and hit t ...more >>
One of the big problems people faced in WSS (V2) was that user was not able to customize out of the box site definitions. One of the big rea ...more >>
A technique we used extensively in STS still applies to WSS: How to get data from your SharePoint lists in XML format. It's actually quite s ...more >>
To protect against cross-site request forgery, be sure your custom built aspx pages call SPUtility.ValidateFormDigest()

3 comments:

  1. Heya i am for the primary time here. I found this board and I in finding It truly
    useful & it helped me out a lot. I'm hoping to provide something back and help others like you aided me.

    My webpage: bancuri scurte noi

    ReplyDelete
  2. I visited various blogs but the audio quality for audio songs current at this
    web page is truly superb.

    My site: bancuri cu fotbalisti

    ReplyDelete
  3. I every time used to read post in news papers but now
    as I am a user of internet thus from now I am using net for
    posts, thanks to web.

    My blog post ... jocuri pian online

    ReplyDelete