Wednesday, June 13, 2007

Run code with full control - no impersonation needed!

Hi all, I am writing this post very exited of a new discovery I have no idea how I missed so far. Every now and than I get to a point in SharePoint that I have to perform some administrative task in the back ground as a result of a reader / contributor action. For example, if i wanted to have a site counter web part, all I needed to do is to update a[Counter] = lastCounter + 1; when a new user enters my site. But - updating is not something anonymous or a reader can do, can they? So - my solution was to create a hidden list with write access to every user and make them write there... Bad idea, i agree. But up untill now - it was the only solution I could think of. Now - after coming across this page in MSDN I can make my web part run a small bit of code as a privileged used.

All I have to do is to create a delegate methond of type "SPSecurity.CodeToRunElevated" and make "SPSecurity.RunWithElevatedPrivileges" run my method in full access mode!
Your code should look something like this:

protected void Button1_Click(object sender, EventArgs e)
SPSecurity.CodeToRunElevated elevatedGetSitesAndGroups = new SPSecurity.CodeToRunElevated(GetSitesAndGroups);

Well, it is too simple to believe... but I know what you are thinking... security breach!

First we have to remember, code running this method must have full code access security trust, I.E have a strong name signing and be installed into GAC folder, so there is little reason for alarm, but still I will investigate this issue further and post my results.
Till then, take care.


Abe said...

Is this meant to only be used in the context of a custom web aprt? B/c I am trying to create a custom site page and I can't seem to get this to elevate properly. The account it is elevated to is the system account yet, I get accessed denied. But when running as the system account, it works just fine. Any ideas?

Shai Ben Shooshan said...

I think i know where your problem is.

Please make sure you create all sites/webs object within the elevated bode block and not before.

also - never use Context objects (like GetContextWeb / SPContext.Current.Web) as they are created under the current user.

do this inside the elevated code if you have the context web object:
web = new SPSite(web.Site.ID).OpenWeb(web.ID);

this will fix your problem...