Wednesday, July 11, 2007

RunWithElevatedPrivileges, watch out for the site context

Soon or later most SharePoint developers use RunWithElevatedPrivileges. We do that either to grant temporary access to files and folders not accessible by the current user or to execute some other action, which requires higher privileges. One thing I constantly forget about that always gets me with an "Access denied" error is when I omit the fact that the SPSite/SPWeb objects are initialized differently for different user contexts. Have a look at this code:

SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPWeb web = SPContext.Current.Web;

// do something that's not allowed for the current user, but it is ok for the elevated user

SPFile file = web.GetFile(restritedFileUrl);

string readProperty = file.Properties["Name"].ToString();
});

Seems like done deal. Not so.... The problem is that the SPWeb object from the current context is initialized using the current user's credentials, so even though we run the code snippet with elevated privileges the actual access to the file is still restricted. To circumvent this we have to create a new SPSite/SPWeb object within the elevated code, where we run in the context of the elevated user. Then we can perform the restricted action. Since the SPSite/SPWeb objects are created explicitly we have to also dispose of them (more about why we need to do this here). The modified working code becomes:

string siteUrl = SPContext.Current.Web.Url;

SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPSite sysSite = new SPSite(siteUrl);
SPWeb sysWeb = sysSite.OpenWeb();

// do something that's not allowed for the current user, but it is OK for the elevated user

SPFile file = sysWeb.GetFile(restritedFileUrl);

string readProperty = file.Properties["Name"].ToString();

sysWeb.Dispose();

sysSite.Dispose();

});

Access granted...

Dovizhdane!

10 comments:

Abram Cardoza said...

I have done all of this yet I still cannot access the resources. When logged in as the system account, all is well, so there are no other issues with the code. Could I have missed some setting in web.config, for example, that is preventing me from running code with elevated privileges?

Mikhail Dikov said...

Abe,

Without knowing the context of your code is hard to respond directly, but keep in mind that when you run with elevated privileges you impersonate the account of the current process. Also verify that all SharePoint objects are derived from within the elevated code block.

Mikhail

Anonymous said...

Thanx for this example, the only one I got to work - with minor adjustment - on my code!

Anonymous said...

Thanks for the code. For now I have only one question. Why this is needed or what does it do?

SPFile file = sysWeb.GetFile(restritedFileUrl); string readProperty = file.Properties["Name"].ToString();

Now I just have to implement my feature with this help and try it.
Thanks.

Mikhail Dikov said...

UroZ,

These lines are simply there to demonstrate an action that requires elevated privileges.

Mikhail

Anonymous said...

Thank you, Thank you, Thank you!

Satyawali said...

This has worked like a gem in my case..in my case the current logged in user didnt have the update permission on a list view so I was getting exception on SpView.update() method call. Even though my whole code was within elevated code block, the update method throws Access denied exception. The same code was working find for authorized members (in leaders grup for the site). I tried your suggestion by creating new SPSite and SPWeb objects initialised from site url as SPContext.Current.Web.Siteurl and i really got access granted on all my operation thereon...thanks much

Unknown said...

Thanks Mikhail,

Your example helped me figure out how to fix a bug in an existing application.

I'd not developed anything within Sharepoint before this and your example was clear and easy to follow.

Mikhail Dikov said...

You are welcome Dan. Thanks for dropping a note.

Rebecca Gordon said...

Thanks for posting this article, it worked a charm for me :)