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

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

  • Comments 15

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
  • PingBack from http://hoursfunnywallpaper.cn/?p=1371

  • 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

  • What kind of operation that you are doing ? Is it a standalone or web application ?

    Thanks,

    Sowmyan

  • 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

  • Thanks for your suggestion :)

    Which line of code erroring out ?

  • 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

  • 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)

  • 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.

  • 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?

  • 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

  • Logic was very helpful.Thanks a lot.

  • Thanks Adrian

    Your comment helped me a lot to sort out my "Access Denied" Issue.

  • 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);

                            }

                        }

                    });

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

  • Thank you very much.. Solved my problem.

Page 1 of 1 (15 items)
Leave a Comment
  • Please add 4 and 4 and type the answer here:
  • Post