Ads

Thursday, 4 April 2013

Different ways run code in Elevated Privileges in SharePoint 2010 development

In SharePoint certain operations has to run with elevated privileges. like, setting information into the property bag of a site needs to be done with elevated privileges.
 
There is a method called SPSecurity.RunWithElevatedPrivileges in the object model that takes a delegate as argument. The delegate is then run with more permissions. An important note regarding this: You must not use old references to SPWeb or SPSite instances inside your delegate, since they are “contaminated” with lower permissions. What you have to do is to create new SPSite and SPWeb instances using the Ids of the sites and webs you already have a reference to, like this
SPSecurity.RunWithElevatedPrivileges(delegate() 
{ 
    using (SPSite site = new SPSite(SPContext.Current.Site.ID)) 
    { 
        using (SPWeb elevatedWeb = site.OpenWeb(webId)) 
        { 
            //Your code here 
        } 
    } 
});
 
If you need to do these kind of operations in several locations, this is a lot of repeating code to include. A colleague of mine made a small helper method that does the setup for elevated privileges for you. Here’s the short code snippet:
 
private delegate void CodeToRunElevated(SPWeb elevatedWeb);
private static void RunElevated(Guid webId, CodeToRunElevated secureCode)
{
    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
        using (SPSite site = new SPSite(SPContext.Current.Site.ID))
        {
            using (SPWeb elevatedWeb = site.OpenWeb(webId))
            {
               secureCode(elevatedWeb);
            }
        }
    });
}
To invoke this, you call on the method with the Id of your web as one argument, and a delegate taking an SPWeb as the other. When the method is invoked, the SPWeb argument will be “uncontaminated” and pushed to elevated privileges. This example sets the name, title, and description of a site.
RunElevated(web.ID, delegate(SPWeb elevatedWeb)
{
    elevatedWeb.Name = siteTitle;
    elevatedWeb.Title = siteTitle;
    elevatedWeb.Description = siteDescription;
    elevatedWeb.Update();
});
 
  1. Passing User Token
  2. SPUserToken is the server model which we use for the purpose. Each user’s token can be represented by this class. The User Token is actually a byte array.
    The SPUser class contains the property named UserToken. Passing a SPUserToken instance into the SPSite constructor impersonates the particular user.
    E.g.: new SPSite(UrlText.Text, user.UserToken);
    For enumerating all the users of a site the web.Users property can be used.
    E.g.: web.Users
 
Now we can try creating list items impersonating each user. The created item will have the system property > Created By set to different users:

The following code performs the same:
Collapse | Copy Code

int count = 1;
foreach (SPUser user in web.Users)
{
    SPSite newSite = new SPSite(UrlText.Text, user.UserToken); // Impersonate
    SPWeb newWeb = newSite.OpenWeb();
    SPListItem item = newWeb.Lists[ListName].AddItem();
    item["Title"] = "Item " + count++.ToString();
    item.Update();

    newSite.Dispose();
    newWeb.Dispose();
}
 
 
 

No comments:

Post a Comment

Ads