1

I have a requirement to be able to always get the logged in user.

The object the calling process is going to pass is the spweb.

As this is legacy code, I cannot change what the calling processes send through, and here's the issue: Some of them pass in the SPWeb running as it is, and some send in an SPWeb that is in elevated priveleges. For the elevated priveleges, the logged in user is returned as System.

In both cases I want to get the current logged in user.

Is this at all possible?

1
  • Would you have access to the SPContext? couldn't you just use that to recover the unelevated user? Commented Apr 9, 2013 at 9:07

2 Answers 2

2

You have two possible situations here.

Case A: you are outside the RunWithElevatedPrivileges scope you may be getting an elevated SPWeb instance that has been saved OUTSIDE the scope of the RunWithElevatedPrivileges delegate. This is a code horror in most cases, but it is still possible. In this case, recreating a new instance based on the url of the elevated one would be enough: the new instance won't be elevated, so you can get your user from there.

Case B: you method is called inside a RunWithElevatedPrivileges delegate In this case recreating the SPWeb instance won't do you any good. Any new instance would still be elevated, so this is a no go. To escape this situation, you need to find an instance that was created outside the elevation scope. How? By exploiting your execution context: for example, in an feature event receiver you could access the web instance in the event properties etc. Since you are in a custom method and you cannot alter the received parameters, you need to access some sort of context. Could you resort to SPContext.Current.Web? That instance isn't elevated, so the user should be the current one browsing the site. That said, you may be in a situation where the context is invalid/null, in which case AFAIK there is no way to obtain the original user from the elevated instance: you will need to store it somewhere (tip: a static singleton?) before entering the elevation context.


EDIT

What to do if your method is called inside a RunWithElevatedPrivileges delegate but you are unsure of having a valid SPContext? This is only a very wild guess, but let's think about it. RunWithElevatedPrivileges will revert to the application pool identity, right? If there isn't an application pool it would mean that there is no app pool identity, so the current user outside and inside the delegate should be the same. If there is an app pool, most time you will have an SPContex, which is unelevated by definition. There are also some specific case where you run in timer jobs and such and the context is null: in that case I believe that you are using the app pool identity anyway, so again, run with elevated should have no effect.

Based on this it would seems that your best bet is to use the user from the SPContex when possible, and assume the elevated and unelevated user to be the same when the context is null. Take that with a grain of salt though...

6
  • you break my heart :) but I think you are 100% correct, thanks! (And to answer your earlier Q, no I don't have access to the context) Commented Apr 9, 2013 at 11:33
  • @MahendranGovender So SPContext.Current is not an option for you? Let me think if any workaround comes to mind. Commented Apr 9, 2013 at 11:47
  • Also - where is your code running? Web part, timer job, desktop app...? Commented Apr 9, 2013 at 11:54
  • All of the above? :) The code is called by event receivers, and also by standard WebParts. Commented Apr 9, 2013 at 12:17
  • urgh. Well... this is only a wild guess but... RunWithElevatedPrivileges would change your identity only when there is an application pool identity to revert to. See above edit to my answer and see if it could make sense for you. Commented Apr 9, 2013 at 12:27
0

as fazio stated the origional developer who made the lagacy code should of used impersonation to pass the SPweb object, but in your case no you cannot!

elevating means your SPWeb object is elevated to the system user and will return that user regardless untill the spweb object is disposed!

SPUser loggedinUser = SPContext.Current.Web.CurrentUser;

the above code would work if its out of the elevated SPWeb object but if its within the elevated block it will return the system account unfortunaly!

Can you post some code? or give us some more info into where your going to use the SPWeb object that is passed? maybe you can use the code above in the current open SPWeb object and then set the SPWeb object to the elevated object?

but short answer is no you cant get the actual logged in user from an elevated user!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.