Welcome to MSDN Blogs Sign in | Join | Help

Why does RunwithElevatedPriviliges not work in Event Handlers?

In SharePoint one of the most used methods is - "RunWithElevatedPriviliges". The common understanding of this method is that - Wrap this delegate around any method you want to run under the context of the app pool user's identity and hence with full permission.

But there are some subtle details which are required to properly use this method. Without knowing the details I guess we end up abusing the "RunWithElevatedPriviliges" method rather than using the method.

Lets go into the detail of how this method actually works. This method internally uses the age old, trusted way of impersonation - WindowsIdentity.Impersonate(). The "RunWithElevatedPriviliges" method was introduced in MOSS 2007 to make impersonation use easy. Now lets understand the intricate requirements for this method to be used properly:-

1. Always use new objects which are within the context of the call. Do not use any object which is outside the scope of the context. In other words, I mean that never use objects from SPContext rather create them using GUID's or other ways within the method call.

E:g. You can get the SPSite or SPWeb object's reference by getting it from SPContext. But for the method - "RunWithElevatedPriviliges" try using the object's created inside the delegate call. Use the objects as shown below (Check The bold text below):-

SPWeb  webInUserContext = SPContext.Current.Web;
SPSite SiteInUserContext = SPContext.Current.Site;
Guid webGuid = webInUserContext.ID;
Guid siteGuid = SiteInUserContext.ID;

SPSecurity.RunWithElevatedPrivileges(delegate()

{
    // get the site in impersonated context
    using (SPSite site = new SPSite(siteGuid))

    {
        // get the web in the impersonated context
                SPWeb web = site.OpenWeb(webGuid);
                // Do your work here  

                web.Dispose();
         }

});

The main reason for doing so is to ensure that all the objects are in the context of the App Pool's identity. This is extremely important to ensure the above point. (And I know that there is very little documentation on this point)

Now lets come to the main point - "RunWithElevatedPriviliges" - With Event Handlers. Normally we make use of the ItemEventProperties object to get the SPSite/SpWeb object. And even if we try to create new objects within the "RunWithElevatedPriviliges" method, we would not be able to get the context of the App Pool identity.

Just Remember one thing:- You can't use "RunWithElevatedPriviliges" with event handlers and the reason is the - ItemEventProperties object. And here is not the end of the problems - you can't even use Windows.Impersonate() as well.

The only workaround which would work here is - Explicit Impersonation. Create a SPUser object for the administrator, get SPToken of the user and then use this token to open the SPSite object using this token.

Sample code is below:-

SPUser user = web.AllUsers["kci\\sp_prodapppool"];

SPUserToken token = user.UserToken;

SPSite kciSite = new SPSite(site.Url, token);

SPWeb kciWeb = kciSite.OpenWeb();

 

Happy Coding :)

Published Monday, July 21, 2008 10:55 PM by varunmalhotra

Comments

# a-foton » Why does RunwithElevatedPriviliges not work in Event Handlers?

Tuesday, November 25, 2008 10:58 AM by jfarrugia

# re: Why does RunwithElevatedPriviliges not work in Event Handlers?

Hi,

I'm at my wit's end trying to solve this problem.  I have tried scores of suggestion all to no avail.  I finally stumbled across this which pretty much sums my experience.  That is that the RunWithElevatedPriviliges technique is useless when it comes to writing EventHandlers.

However, I can't understand the Explicit Impersonation technique you described above.  From where should I get the "web" reference; same applies for the "site".  In my case the only properties I can access or modify from the SPItemEventProperties object when executing the event handler in normal user mode are the Cancel and ErrorMessage.

I appreciate any feedback cos I'm close to giving up on this one.

Thanks a lot.

James

Tuesday, November 25, 2008 12:35 PM by varunmalhotra

# re: Why does RunwithElevatedPriviliges not work in Event Handlers?

Hi James,

SPsite and SPweb objects can be obtained from either the

SPWeb  web = SPContext.Current.Web;

SPSite site = SPContext.Current.Site;

or the

SPWeb web = properties.OpenWeb();

SPSite site = properties.OpenWeb().Site;

I hope this helps.

Regards,

Varun

Wednesday, November 26, 2008 10:15 AM by jfarrugia

# re: Why does RunwithElevatedPriviliges not work in Event Handlers?

Hi Varun,

Thanks for your immediate feedback.  Problem is that the access denied error is also thrown when invoking the OpenWeb() method on the properties object.  It's almost as if you can't do anything really useful in an event handler if you're not an admin.

Regards,

James

Wednesday, November 26, 2008 10:23 AM by varunmalhotra

# re: Why does RunwithElevatedPriviliges not work in Event Handlers?

Hi James,

Okay. So may I know which event handler are you writing the code in. Also, does SPContext work or even that doesn't work.

Regards,

Varun

Thursday, November 27, 2008 8:08 AM by jfarrugia

# re: Why does RunwithElevatedPriviliges not work in Event Handlers?

Hello Varun,

Yes sure.  Let me tell you what I'm trying to achieve.  I created a survey out of the box which is supposed to represent a nomination form to be filled in by staff.

People basically vote for their peers in specific categories.  In the end the top-most voted person in each category will win a commendation or a prize.

Each question is associated with a "People Picker" field.  I wanted to implement some simple validation such that:

* a user can't vote for him/herself

* a user can't vote for certain members of top management

The idea was to implement an event handler which would be invoked upon the ItemAdding event of a Survey List.  There I would check the contents of the fields (via the AfterProperties property of SPItemEventProperties) and either cancel the survey issuing an error message or do nothing (i.e. survey accepted)

As long as the survey is carried out by an admin (or a user member of the admin group), the event handler works fine.  But as soon as the survey is answered by regular users (having contribution permissions) I start getting these AccessDenied errors.

Even stranger, the event handler keeps executing even after being deactivated (I wrapped the event handler in a feature and deploy it via stsadm)

I'm really at a loss...

Anonymous comments are disabled
 
Page view tracker