Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does RunWithElevatedPrivileges fail to execute?

I'm trying to make a web part that greps user comments and stores it in custom list, I wrote this code to add a list to the site once the web part added to the page,

[Guid("c314a0e8-0210-4064-b79e-bfd3594c6083")]
public class CommentWriteSpace : System.Web.UI.WebControls.WebParts.WebPart
{
    SPSite site = null;
    SPWeb web = null;

    public CommentWriteSpace()
    {
        SPSecurity.CodeToRunElevated foo = new SPSecurity.CodeToRunElevated(doit);

        SPSecurity.RunWithElevatedPrivileges(foo);
        SPListCollection listCollection = web.Lists;

        Guid listGuid = listCollection.Add("Comments List", "A list of user comments", SPListTemplateType.GenericList);
        listCollection[listGuid].Fields.Add("User", SPFieldType.User, true);
        listCollection[listGuid].Fields.Add("Comment", SPFieldType.Text, true);
        listCollection[listGuid].OnQuickLaunch = true;
        listCollection[listGuid].Update();
        //this.Page.Request.Url.ToString()
    }

    public void doit()
    {
        site = SPContext.Current.Site;
        web = site.OpenWeb();
    }
}

But the RunWithElevatedPrivileges method throw an exception, I guess it's a permission issue, the exception is the same as one appears when executing site.OpenWeb(); method without elevating privileges.

What could be the problem?

like image 384
netseng Avatar asked May 12 '26 17:05

netseng


2 Answers

You're seeing a number of problems:

  1. SPSite object permissions are determined when they are created, so SPContext.Current.Site will already have the permissions of the current user even if you get the reference within RWEP.
  2. Passing SP objects out of a RWEP block is unsupported and generally dangerous. If you do need to use RWEP, all SPSite and SPWeb objects (and their children) created within that context should be used and disposed in the CodeToRunElevated.
  3. Each call to listCollection[listGuid] will create a new SPList object, which may cause unexpected behavior.

As Dan suggests, RWEP is not the preferred method to do what you're trying to accomplish. Using an extension from the link he references, I would rewrite to look something like this:

[Guid("c314a0e8-0210-4064-b79e-bfd3594c6083")]
public class CommentWriteSpace : System.Web.UI.WebControls.WebParts.WebPart
{
    public CommentWriteSpace()
    {
        SPContext.Current.Site.RunAsSystem(UpdateSite);
        //this.Page.Request.Url.ToString()
    }

    public void UpdateSite(SPSite site)
    {
        SPWeb web = site.RootWeb;

        SPListCollection listCollection = web.Lists;
        Guid listGuid = listCollection.Add("Comments List", "A list of user comments", SPListTemplateType.GenericList);
        SPList list = listCollection[listGuid];

        list.Fields.Add("User", SPFieldType.User, true);
        list.Fields.Add("Comment", SPFieldType.Text, true);
        list.OnQuickLaunch = true;
        list.Update();
    }
}
like image 186
dahlbyk Avatar answered May 14 '26 16:05

dahlbyk


There is no need for you to run SPContext.Current.Site with elevated privileges. In fact, I think this is why you get the exception. Furthermore, you could also use SPContext.Current.Web instead of site.OpenWeb(). The latter creates a new SPWeb object that you will be responsible of disposing again. SPSite and SPWeb objects from SPContext are automatically disposed when the HTTP request has completed.

like image 29
Lars Fastrup Avatar answered May 14 '26 18:05

Lars Fastrup



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!