次の方法で共有


SPSecurity.RunWithElevatedPrivileges - an important point while using it in web context

Normally we will use SPSecurity.RunWithElevatedPrivileges() to execute some code that has to be run under some higher privileges.

Whenever we use SPSecurity.RunWithElevatedPrivileges(), it will execute the code under the context of Application Pool identity. Now we can see a scenario where we will get the “Access denied” exception from the code block even if you use SPSecurity.RunWithElevatedPrivileges.

This was the code snippet that I have used initially inside a custom webpart to read XML content from of an InfoPath form which was uploaded in a document library. This code will throw an “Access denied” exception while calling the OpenBinaryStream() method whenever I execute it through an Anonymous user account.

SPSecurity.RunWithElevatedPrivileges(delegate()

 {

      SPWeb oWeb = SPContext.Current.Web;

      SPList oList = oWeb.Lists["InfoPathLib"];

      SPListItem oListItem = oList.Items[0];

      Stream oStream = oListItem.File.OpenBinaryStream();

      StreamReader oReader = new StreamReader(oStream);

      string strLine = "";

     

      strLine = oReader.ReadLine();

     

      oReader.Close();

      oStream.Close();

      oReader.Dispose();

      oStream.Dispose();

      lblFileContent.Text = strLine;

      this.Controls.Add(lblFileContent);

 });

Here the problem was, whenever we take the SPWeb instance using

SPWeb oWeb = SPContext.Current.Web;, then SPWeb instance still running under anonymous account only , because we are taking it through the current web context in which the current user is running under anonymous account (IUSR_MachineName). That was the reason that we got that “Access Denied” exception. We need to remember this point all time whenever we use RunWithElevatedPrivileges under the web context.

So what we need to that, we have to take the current context outside the SPSecurity.RunWithElevatedPrivileges block and then create a new instance of SPSite and SPWeb inside the that block which will run under application pool identity.

SPWeb oWeb1 = SPContext.Current.Web; // taking the current SPWeb context running under the anonymous account

SPSecurity.RunWithElevatedPrivileges(delegate()

{

using (SPSite oSite = new SPSite(oWeb1.Site.Url))

{

// creating a new SPSite running under Application pool idenity

using (SPWeb oWeb = oSite.OpenWeb())

{

SPList oList = oWeb.Lists["InfoPathLib"];

SPListItem oListItem = oList.Items[0];

Stream oStream = oListItem.File.OpenBinaryStream();

StreamReader oReader = new StreamReader(oStream);

string strLine = "";

strLine = oReader.ReadLine();

oReader.Close();

oStream.Close();

oReader.Dispose();

oStream.Dispose();

lblFileContent.Text = strLine;

this.Controls.Add(lblFileContent);

}

}

});

The above code will work fine and we can read the InfoPath document. So, please do not forget to create a new instance of SPSite and SPWeb inside SPSecurity.RunWithElevatedPrivileges,while using it in a web context.

 

 

Another work-around to this paritcular requirement (read the file content) is - use GetFileAsString() method of the SPWeb directly. And here there is no need to use the SPSecurity.RunWithElevatedPrivileges. Since, I have enabled anonymous authentication on this SharePoint web application it will allow to read the file using the below method under the context of anonymous account.

string

strXML = SPContext.Current.Web.GetFileAsString("/FannyDocLib/Form1.xml");

Comments

  • Anonymous
    August 13, 2008
    PingBack from http://hoursfunnywallpaper.cn/?p=1371

  • Anonymous
    December 31, 2008
    Hi, I have still having access denied error. It shows me that you logged in with Application pool account but still having access denied error. Thanks, Dhams

  • Anonymous
    April 01, 2009
    What kind of operation that you are doing ? Is it a standalone or web application ? Thanks, Sowmyan

  • Anonymous
    June 01, 2009
    Don't forget to Dispose() your SPSite and SPWeb objects!! But only if they're not equal to the SPContext.Current.Site / SPContext.Current.Web. The code as you posted above WILL cause memory leaks (and LOTS of messages in your SharePoint logs)! Back on topic, I have a similar problem, getting an Access Denied exception within a RunWithElevatedPrivileges block. Except in my case, I already have instantiated all the objects being used within the elevated block. Can't figure what's going on there, but the code is working on one machine and not on another. Which leads me to believe that maybe something like the app pool account doesn't enough rights. We thought maybe resetting IIS would help, but no. The only thing left to try is to reboot the server.. I just assumed that permissions were irrelevant when using RunWithElevatedPrivileges. I think now I can safely assume that that assumption was incorrect. Does anyone know what exactly controls what RunWithElevatedPrivileges is allowed to do..? Cheers -Adrian

  • Anonymous
    June 02, 2009
    The comment has been removed

  • Anonymous
    June 02, 2009
    I was getting the access denied exception from this code: SPSecurity.RunWithElevatedPrivileges(delegate()            { SPSite elsite = new SPSite(Page.Request.Url.ToString()); SPWebApplication elapp = elsite.WebApplication; elapp.FormDigestSettings.Enabled = false; //... The exception was coming from setting the FormDigestSettings.Enabled = false. We eventually found the cause of the problem to be the Application Pool Account ("Content Access Account") not being a member of the "Farm Administrators" SharePoint group. The Farm Administrators are accessed from Central Administration > Operations > Security Configuration > Update farm administrator's group. Once the Application Pool ("Content Access") account was a farm administrator, there was no more problems. It turns out that by default, the Content Access account isn't a farm administrator. To modify the properties of the SPWebApplication object, Site Collection Administrator rights isn't enough, since the site collection is a child of the web application. The web application is a child of the farm, so Farm Administrators can change it's properties. This wasn't exactly obvious to begin with, but now that the problem has been solved, it makes sense. I hope this saves someone else some trouble. -Adrian

  • Anonymous
    July 22, 2009
    Why o why is the SPWeb object NOT disposed when using it in a “using” statement inside RunWithElevatedPrivileges(). Is this a known buck or what? This code will cause a warning in the SP log: SPSecurity.RunWithElevatedPrivileges(delegate() {  using (SPSite oSite = new SPSite(oWeb1.Site.Url)) {    using (SPWeb oWeb = oSite.OpenWeb()) {      ….    }  }   }); .. Potentially excessive number of SPRequest objects (9) currently unreleased on thread 1.  Ensure that this object or its parent (such as an SPWeb or SPSite) is being properly disposed. Is that not the point in using “using” statement for auto-disposal? (http://msdn.microsoft.com/en-us/library/aa973248.aspx)

  • Anonymous
    September 17, 2009
    You can see those kinds of logs in the ULS log because those are written from the SharePoint httpmodule, SPRequestModule , because it will keep track of all the SPRequest class objects and finally whenever the EndRequest calls it will writes those details into the ULS and it is not always coming from ur code.

  • Anonymous
    February 26, 2010
    This is working perfectly when I applied it to my web part.  In testing my Anonymous user can now display list attachments however it seems from everything I have read this should be applied to this web part only but I seems that the anonymous user has these elevated privileges until he closes the site.  Am I missing something?

  • Anonymous
    August 31, 2010
    I ran into an issue when using RunWithElevatedPrivileges, if you try to update a list it will throw and InvalidOperationException, in the following blog entry is the solution: blog.jussipalo.com/.../moss-splistitemupdate-throws-error.html

  • Anonymous
    December 14, 2010
    Logic was very helpful.Thanks a lot.

  • Anonymous
    October 26, 2012
    Thanks Adrian Your comment helped me a lot to sort out my "Access Denied" Issue.

  • Anonymous
    April 21, 2013
    Hi, I am trying below code to create content database , but it is still giving  "Access Denied " ! Any solution ?            SPWeb oWeb1 = SPContext.Current.Web;                 SPSecurity.RunWithElevatedPrivileges(delegate()                 {                     using (SPSite oSite = new SPSite(oWeb1.Site.Url))                     {                         // creating a new SPSite running under Application pool idenity                         using (SPWeb oWeb = oSite.OpenWeb())                         {                             SPContentDatabase currentSiteDatabase = oWeb.Site.ContentDatabase;                             SPWebApplication elevatedWebApp = oWeb.Site.WebApplication;                             elevatedWebApp.ContentDatabases.Add   (currentSiteDatabase.Server, "WSS_Content_1111_3", null, null, 0, 1, 1);                         }                     }                 });

  • Anonymous
    August 13, 2013
    Great post. Although it’s a common need, it’s not so easy to figure out the solution. Solved my problem.

  • Anonymous
    October 21, 2013
    Thank you very much.. Solved my problem.

  • Anonymous
    June 22, 2015
    Would like to thank Adrian in the comment section whose pointers helped me solve my issue. Thank you to the author for posting this. After 7 years it is still relevant!

  • Anonymous
    December 13, 2015
    I thought I would mention the issue I had was the SPList item need to be fetch again.   using (SPWeb web = SiteCollection.OpenWeb())                    {                        web.AllowUnsafeUpdates = true;                        var item =  web.Lists[librarylocation].GetItemById(name.Item.ID);                        var userName = user.LoginName;                        try                        {                            item.BreakRoleInheritance(true); Now the item inheritance could be broken, with no access denied error