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=1371Anonymous
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, DhamsAnonymous
April 01, 2009
What kind of operation that you are doing ? Is it a standalone or web application ? Thanks, SowmyanAnonymous
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 -AdrianAnonymous
June 02, 2009
The comment has been removedAnonymous
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. -AdrianAnonymous
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.htmlAnonymous
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