We often use RunWithElevatedPrivileges to elevate permissions and execute a block code as the application pool account.
Like this:
SPSecurity.RunWithElevatedPrivileges(delegate() { // Code to run under the app pool account });
This works nicely inside WSPs. However, I recently noticed an unexpected difference between how RunWithElevatedPrivileges works inside web parts and other code running in the SharePoint context versus how it works when executing from the console.
Let’s say you have the following code in a console application:
SPSecurity.RunWithElevatedPrivileges(delegate () { using (SPSite site = new SPSite("MySiteAbsoluteUrl")) { using (SPWeb web = site.OpenWeb()) { Console.WriteLine(web.CurrentUser.LoginName); Console.WriteLine(WindowsIdentity.GetCurrent().Name); } } });
Note that I’m logged in to this SharePoint box as DOMAIN\ehik. My original expectation was that since the RunWithElevatedPrivileges construct executes code under the application pool account, the output of lines 7 and 8 above should reflect the newly elevated privileges.
Expected Output
- Line 7: App pool account login name (Not DOMAIN\ehik)
- Line 8: DOMAIN\ehik
Actual Output
- Line 7: DOMAIN\ehik
- Line 8: DOMAIN\ehik
See, elevation doesn’t work at all!
After some investigation, I confirmed that for console applications, RunWithElevatedPrivileges pretty much doesn’t work. No elevation occurs. The code runs under your own credentials.
If you must execute the above code as the application pool account, you would need to manually instruct your .exe to “Run As” the SharePoint application pool account.
Forget elevation. Use impersonation.
If we modify the above code to use SharePoint user impersonation instead of RunWithElevatedPrivileges, we immediately get the expected results. Let’s change the code to this (notice that I’m not using the RunWithElevatedPrivileges wrapper):
using (SPSite site = new SPSite("MySiteAbsoluteUrl")) { using (SPWeb web = site.OpenWeb()) { Console.WriteLine(web.CurrentUser.LoginName); Console.WriteLine(WindowsIdentity.GetCurrent().Name); using (SPSite impersonatedSite = new SPSite("MySiteAbsoluteUrl", site.SystemAccount.UserToken)) { using (SPWeb impersonatedWeb = impersonatedSite.OpenWeb()) { Console.WriteLine(impersonatedWeb.CurrentUser.LoginName); Console.WriteLine(WindowsIdentity.GetCurrent().Name); } } } }
The lines of interest this time are lines 5, 6, 11, and 12.
Output
- Line 5: i:0#.w|DOMAIN\ehik (That’s just the claims format for my login name. No problem.)
- Line 6: DOMAIN\ehik
- Line 11: SHAREPOINT\system (Impersonation works!)
- Line 12: DOMAIN\ehik
Conclusion
For console applications, RunWithElevatedPrivileges is a waste of time. Use SharePoint user impersonation instead.
I wrote a more detailed article on performing SharePoint user impersonation here.
That is because Console is not defined within the block. Try defining a list variable and assigning a sharepoint list to that variable outside the elevated priviliges block. Now get times from the list variable inside the privileges block. It will get items as current user and not as app pool account. That is because the list was not defined and assigned within the privileges block. Same thing is true for console here.
Thanks for your contribution Deepa!
I understand the scenario you’re describing and have experienced it too. However, in this case, the “Console” object itself is not the object of interest. The object of interest is the SPWeb object which you may notice has been properly instantiated inside the elevated privileges block. I simply used Console.WriteLine to explain the problem. This blog post was prompted by my failure to get RunWithElevatedPrivileges (RWEP) working as expected in console applications (with SP objects that have been instantiated inside the RWEP block of course).
– Are you trying to explain why RWEP in console applications behaves the way this article says it does? (I know I simply identified the RWEP problem without really explaining why it occurs).
OR
– Are you trying to say that RWEP will work as expected if I just change my code?
If the latter is true, then do you happen to have sample code that executes as the app pool account, using RWEP, and in the context of a console application? If you do, please share! I’d really love to see.
Thanks again for commenting. Great to see you here 🙂