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!

5 comments:

Abe 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!

UroZ 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