Sunday 10 February 2013

How to Properly use RunWithElevatedPrivileges

RunWithElevatgedPrivileges will run the code block with Full Control rights even if the current user does not have full control.  This piece can be very useful, but must be used carefully to avoid creating a security hole.
The interesting part of this method is that for any objects to be run with this elevated context, they must be created within the RunWithElevatedPrivileges block.  This may seem obvious but lets take a look at a couple examples:
  
SPWeb web = SPContext.Current.Web;
SPSecurity.RunWithElevatedPrivileges(delegate()  
       {  
         PublishingWeb pWeb = PublishingWeb.GetPublishingWeb(web);
         ...
       })  

This method will result in an unauthorized error, unless the logged in user has enough permissions to open a Publishing Web object.  But we said the object must be created within the Elevelvated Permission block, so it looks like an easy fix to the above code:


SPSecurity.RunWithElevatedPrivileges(delegate()  
       {
        SPWeb web = SPContext.Current.Web;
         PublishingWeb pWeb = PublishingWeb.GetPublishingWeb(web);
         ...
       })

This method will also result in an unauthorized error.  Wait you say, the SPWeb object is created within the Elevated block, so it should work.  The issue is that the SPContext.Current.Web method returns an SPWeb object under the context of the current user, not the Elevated user, regardless of where the method is run...so how do you get an SPWeb object to run under the elevated permission?  You need to open the web using the GUID constructor, like this:


Guid siteID = SPContext.Current.Site.ID;
Guid currentWebID = SPContext.Current.Web.ID;

SPSecurity.RunWithElevatedPrivileges(delegate()
            {
             using (SPSite site = new SPSite(siteID))
                {
                    SPWeb currentWeb = site.OpenWeb(currentWebID);
                    PublishingWeb pWeb = PublishingWeb.GetPublishingWeb(web);
                    ...
                }
            })


The difference being the first and second examples are returning an already created SPWeb object, that was created under the current users context.  The last example is returning newly created SPSite and SPWeb objects, since they are within the elevated code block they will be created under the elevated context.  Now everything should work as expected, regardless of who is logged into the site.

             



No comments:

Post a Comment