Wednesday, March 13, 2013

Access denied within SPSecurity.RunWithElevatedPrivileges

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["TestList"];

 });

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["TestList"];

                    }
                }

            });
The above code will work fine. So, please do not forget to create a new instance of SPSite and SPWeb inside SPSecurity.RunWithElevatedPrivileges,while using it in a web context.

No comments:

Post a Comment