Question

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?

Was it helpful?

Solution

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...

OTHER TIPS

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!

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top