A simple code impersonation in Sharepoint

Hello Everyone,

In this article i share with you a sample function that provide us code impersonation.For example you have login to sharepoint as system account and what to add an item to a custom list but you impersonate it by another user. As you know SPSecurity.RunWithElevatedPrivileges can provide us to run code as Sharepoint\system account.
So what if you impersonate with another user. The main key point is SPSite object constructor has parameter as SPUserToken, if you pass this token to the constructor,
it provide execute code with related user rights as defined with SPUserToken. For a real code impersonation you should better to use some native dll references (AdvApi32 DLL) . but this is also work for simple operations well.

Here the RunAsAdmin static class that contains ImpersonateRun fuction getting 2 parameters .
1) Account : the account to use rights
2) RunWithAdminDelegate : which is a delegate that provide us writing less codding for our implementations using lambda functions

Code Impersonation Sample
  1. public static class RunAsAdmin
  2. {
  3.     public delegate void RunWithAdminDelegate(SPSite site, SPWeb web);
  4.     public static void ImpersonateRun(string account,RunWithAdminDelegate myDelegate)
  5.     {
  6.         Guid webID = SPContext.Current.Web.ID;
  7.         Guid siteID = SPContext.Current.Site.ID;
  8.         SPUser privilegedAccount =null ;
  9.         if(string.IsNullOrEmpty(account))
  10.         {
  11.             privilegedAccount = SPContext.Current.Web.CurrentUser;
  12.         }
  13.         else
  14.         {
  15.             privilegedAccount = SPContext.Current.Web.EnsureUser(account);
  16.         }
  17.         SPUserToken privilegedToken = privilegedAccount.UserToken;
  18.         using (SPSite site = new SPSite(siteID, privilegedToken))
  19.         {
  20.             site.AllowUnsafeUpdates = true;
  21.             using (SPWeb web = site.OpenWeb(webID))
  22.             {
  23.                 //SPWebApplication webApp = web.Site.WebApplication;
  24.                 //  webApp.FormDigestSettings.Enabled = false;
  25.                 web.AllowUnsafeUpdates = true;
  26.                 myDelegate.Invoke(site, web);
  27.                 web.AllowUnsafeUpdates = false; ;
  28.                 //   webApp.FormDigestSettings.Enabled = true;
  29.             }
  30.         }
  31.     }
  32. }

the usage is very simple , Less coded less simple .

The usage
  1. protected void Page_Load(object sender, EventArgs e)
  2. {
  3.     RunAsAdmin.ImpersonateRun(“BLOG\\bpostaci”, (site, web) =>
  4.     {
  5.         SPList list = web.Lists[“MyList”];
  6.         foreach (SPListItem item in list.Items)
  7.         {
  8.             //Add Some items.
  9.         }
  10.     });
  11. }

see you next time.

Advertisements

Sharepoint RunWithElevatedPrivileges and Access Denied error

Hi everyone,

in this short article i try to explain most common error of Access Denied cause by misusage of SPSecurity.RunWithElevatedPrivileges() method.

Here is the wrong code sample:

SPSecurity.RunWithElevatedPrivileges(delegate()
{
    //never use like this
    SPList list = SPContext.Current.Web.Lists["SomeList"];
    SPListItem item = list.GetItemById(12);
    item["Title"] = "Some Changes";
    item.Update();
});

The code defined above cause Access Denied when a user request without privs. Beacuse SPContext still contains unpriviledged user rights.If you call any object from SPContext it work with actual user (unpriviledged) rights not the admin rights.

Now is the correct one:

Guid webID = SPContext.Current.Web.ID;
Guid siteID = SPContext.Current.Site.ID;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
    using (SPSite site = new SPSite(siteID))
    {
        site.AllowUnsafeUpdates = true;
        using (SPWeb web = site.OpenWeb(webID))
        {
            web.AllowUnsafeUpdates = true;
            SPList list = web.Lists["SomeList"]; //attention here !!!
            SPListItem item = list.GetItemById(12);
            item["Title"] = "Some Changes";
            item.Update();
        }
    }
});

Yep its a little extra codding . I give you a good pattern for using this with more easy and shorter usage:
I created once a static class and add to my project this class named RunAsAdmin and one static method named Run which is taking a delegate method for run our  RunWithElevatedPrivileges codes.

public static class RunAsAdmin
{
    public delegate void RunWithAdminDelegate(SPSite site, SPWeb web);
    public static void Run(RunWithAdminDelegate myDelegate)
    {
        Guid webID = SPContext.Current.Web.ID;
        Guid siteID = SPContext.Current.Site.ID;
        SPSecurity.RunWithElevatedPrivileges(delegate()
        {
            using (SPSite site = new SPSite(siteID))
            {
                site.AllowUnsafeUpdates = true;
                using (SPWeb web = site.OpenWeb(webID))
                {
                    web.AllowUnsafeUpdates = true;
                    myDelegate.Invoke(site ,web );
                }
            }
        });
    }
}

Usage of this code is:

RunAsAdmin.Run((site,web)=>
 {
    SPList list = web.Lists["SomeList"];
    SPListItem item = list.GetItemById(12);
    item["Title"] = "Some Changes";
    item.Update();
});

Its very useful :))
Happy coding with sharepoint 🙂