ASP.NET impersonation in SharePoint 2010 service applications

Since last few hours I was working on one interesting code problem with @jthake might as well share it here too!

Here is the scenario: you need to call SharePoint 2010 Service application functionality under the credentials of another user. For example you want to cast a rating as another user or post a comment as another user etc.
Many of the SharePoint 2010 Service Application manager classes such as SocialCommentManager use HttpContext.Current to grab users identity and even if you RunWithElevatedPrivileges the identity of the current user will remain in the context and therefore methods will be executed under the user account or the original user.

Here is the approach: Now, this will largely depend on case by case on what service application you’re using but the drill is pretty much the same.
1. Impersonate ASP.NET context, here is the article I found handy
2. Create new context with impersonated user’s identity
3. Execute your custom Service application code
4. Stop impersonation

1. As article at echnet suggests we make WindowsIdentity.GetCurrent() to have the identity of our desired user

WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;

if (RevertToSelf())
{
if (LogonUserA("myusername", "mydomain", "mypassword", LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
}
}
}

2. Now we’ll create a context with current users identity (credits to @jthake for this piece of code)

IPrincipal principal = new GenericPrincipal(WindowsIdentity.GetCurrent(), new string[0]);
HttpRequest request = new HttpRequest("", "http://localhost", "");
HttpContext.Current = new HttpContext(request, new HttpResponse(new StringWriter(CultureInfo.CurrentCulture)));
HttpContext.Current.User = principal;

3. Now you execute your custom code under newly impersonated service context:

SPServiceContext serviceContext = SPServiceContext.GetContext(HttpContext.Current);
// .... your custom code here

4. Stop impersonation

impersonationContext.Undo();

Good Luck!

This entry was posted in sharepoint, sharepoint 2010 and tagged , , , . Bookmark the permalink.

Comments are closed.