Wednesday 16 December 2015

Use of RunWithElevatedPrivileges? or When and How to use RunWithElevatedPrivileges?

Basically the code executed inside this method has "System Account" privileges in addition to the current user privileges
OR
In a better way - we can tell that this method runs under the Application Pool identity, which has site collection administrator privileges on all site collections hosted by that application pool.

All the operations done inside this method should use a new SPSite Object. This means that the SPSite variables that are instantiated or created outside the subset code of this method can't be used for security elevation and it will result with the “Access denied error”

Correct Usage Sample:

                   
SPSecurity.RunWithElevatedPrivileges(delegate()
{
                    //New SPSite object.
     using (SPSite site = new SPSite(web.Site.ID))
     {
                    //Do things by assuming the permission of the "system account".
     }
});

The above mentioned code snippet is the exact usage of the RWEP and if we try to use the SPSite objects created outside the RWEP method like this...
Faulty Usage:
                    
                    //SPSite Object created outside the RWEP Method
                    SPSite  site = new SPSite("siteURL");
 
                    SPSecurity.RunWithElevatedPrivileges(delegate()
                    {
                                          using (SPWeb web = site.OpenWeb())
                                         {
                                                              string user = web.CurrentUser.Name;
                                              //Operations that need high level access.
                                          } 
                     });
 
...it will give an “Access denied” error for operations that need higher level of access, because the user will be the currently logged in user, not the “System Account”
If we look inside the “Microsoft.SharePoint.dll” and look at the RWEP method internals, we can see that it uses the WIN32API for the impersonation of the current thread. Actually it doesn't create a new instance thread for this elevated code execution rather it just impersonates during elevated code execution and reverts back to the current user's identity after the elevated code execution. This can cause unpredictable/obscure issues with your application.
* RWEP doesn't allow changing the farm level or SSP level object properties.



Alternative impersonation technique to RunWithElevatedPrivileges() method:

A practical alternative to the RWEP method is to use SPUserToken of the SystemAccount directly with SPSite object. We can either create a new SPSite instance from the existing SPSite Object, whose constructor will be provided by the "UserToken" of the System Account or we can assign the "UserToken" property of the SPSite object, see the below code snippet.
  
  //Creating a SPUsertoken object.
  SPUserToken saUserToken =SPContext.Current.Site.SystemAccount.UserToken;
  //passing to the constructor of the SPSite
  SPSite spSite=new SPSite("siteURL",saUserToken);

Or we can use it like this.
  
  SPUserToken saUserToken = SPContext.Current.Site.SystemAccount.UserToken; 
  SPSite spSite=new SPSite("siteURL");
  //assigning the UserToken property of SpSite.
  spSite.UserToken = saUserToken; 

In the above technique, there is no case of obscure bugs that may occur with RWEP and we can use the existing SPSite Objects for impersonation too, hence we can solve the restrictions when using the RWEP method.

No comments:

Post a Comment