Impersonate SharePoint User

This is a post that I’d imagine most people who have been developing with SharePoint will be aware of but I thought it might be worthwhile blogging about.

I’ve seen code where people have tried to impersonate a user to perform actions against a SharePoint file by using the LogonUser function.

[System.Runtime.InteropServices.DllImport("ADVAPI32.DLL")]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out int phToken);

When working with SharePoint, there is no need for this. For starters, the above function requires you to know the user’s password. Now, of course, there are good reasons why the business rules may require this and I’m not saying it shouldn’t be implemented that way. For the scenarios where this is not required, there’s a very easy and simple way of impersonating a valid SharePoint user, without having to know their password.

One simple way of impersonating another user is to wrap the Microsoft.SharePoint.SPSecurity.RunWithElevatedPrivileges method around your code. This will ensure all objects created within the method are executed as the application pool user. There’s no point in wrapping this around code like the following sample.

SPContext.Current.ListItem["a field"] = "a value";

This will execute as the currently logged in user and not the elevated user. To run as the elevated user it’s important to open the site or web objects while inside the method.

SPSecurity.RunWithElevatedPrivileges(() =>
{
    using (SPSite site = new SPSite(SPContext.Current.Site.ID))
    {
        using (SPWeb web = site.OpenWeb(SPContext.Current.Web.ID))
        {
            SPListItem item = web.GetListItem(SPContext.Current.ListItemServerRelativeUrl);
            item["a field"] = "a value";
        }
    }
});

But I digress, the point of this post was to demonstrate how to impersonate a specific user and not the application pool user for the current web application.

If the code above executed as the application pool user, the following will execute as the user Joe Bloggs. There is no exception handling, so obviously if the user did not exist in the site the code would fail but it shows you how to impersonate an individual user by using their token.

SPUser jbloggsUser = SPContext.Current.Web.AllUsers["domain\jbloggs"];
using (SPSite site = new SPSite(SPContext.Current.Site.ID, jbloggsUser.UserToken))
{
    using (SPWeb web = site.OpenWeb(SPContext.Current.Web.ID))
    {
        SPListItem item = web.GetListItem(SPContext.Current.ListItemServerRelativeUrl);
        item["a field"] = "a value";
    }
}

The difference with this code is with the SPSite constructor, where we pass the SPUserToken object for Joe Bloggs. The containing code will now execute as this user.

2 comments

  1. P. Lamping says:

    I’ve been looking for code like this. I want to develop something that impersonates a user so I can find out what is causing the errors they are getting. One thing I want to do is get the password that’s in the user’s SSO database. I placed your code around my code to get the password, and it’s still getting the password of the current user (me) instead of the user I entered into the input field. Here is my code:

    creds = provider.GetCredentials(ssoApp);
    pPassword = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(creds.Password);
    SSOuserPassword = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(pPassword);

    Is it possible that Microsoft does not allow anyone to get the credentials of another user due to security restrictions on the SSO database, even with this impersonation code around it?

    • Stu says:

      Just noticed this in my pending comments…..sorry!

      The code inside the “using (SPSite…” block will only execute as the provided user if the objects are retrieved by using the SPSite object, which does not apply to your SsoCredentials object.

Leave a Reply

Your email address will not be published. Required fields are marked *

Solve the maths problem shown below before posting: *

Follow

Get every new post delivered to your Inbox

Join other followers: