Proper use of SPWeb.EnsureUser and alternatives

Often in SharePoint development, you’ll get a domainusername from which you want to get the corresponding SPUser object or other SharePoint objects related to an NT login. The SharePoint object model provides a handy method, SPWeb.EnsureUser to check whether a NT login belongs is associated with a web, and if not, it handles creating the user on that web. When code is doing more than reading from SharePoint objects, you’re going to need elevated privileges. Why? Because that code could run under the context of a user without administrative privileges, and you’ll get errors. Using SPSecurity.RunWithElevatedPrivileges is probably the best way to elevate the code to run with system-account privileges.

In the example below, I use the domainusername to add a permission to a list item for that user. The code is geared toward an item-event receiver, but can be adapted to other uses.

/// <summary>
/// Adds an item-level permission for a user.
/// </summary>
/// <param name="loginNameField">the username, such as DOMAINuseralias</param>
/// <param name="permissionName">the permission name, such as Contribute</param>
/// <param name="properties">the item event properties object</param>
public static void addUserPermission(string loginNameField, string permissionName, SPItemEventProperties properties)
{
    try
    {
        SPSecurity.RunWithElevatedPrivileges(delegate()
        {
            using (SPSite site = new SPSite(properties.SiteId))
            {
                site.AllowUnsafeUpdates = true;
                using (SPWeb web = site.OpenWeb(properties.RelativeWebUrl))
                {
                    web.AllowUnsafeUpdates = true;
                    SPUser user = web.EnsureUser(properties.ListItem[loginNameField].ToString());
                    SPRoleAssignment userPermission = new SPRoleAssignment(user);
                    SPRoleDefinition role = web.RoleDefinitions[permissionName];
                    userPermission.RoleDefinitionBindings.Add(role);
                    SPListItem item = web.GetListItem(properties.RelativeWebUrl + "/" + properties.ListItem.Url);
                    item.RoleAssignments.Add(userPermission);
                    item.SystemUpdate();
                }
            }
        });
    }
    catch (Exception ex)
    {
        //TODO: Handle error
    }
}

What if SPWeb.EnsureUser doesn’t work for you? Are you sure you’re passing the domainuseralias and not just the user alias? If you only have the user alias, you can use the System.Security.Principal namespace. For example, the following code takes the user alias, which the NTAccount constructor takes as a parameter (it also takes the domain name if you’ve got it).  Thanks to my colleague David Cooper for the code example.  Check out this blog for more background on SIDs. I’m not sure what would happen if you had more than one alias in a forest, e.g., DOMAIN1john.doe and DOMAIN2john.doe.

/// <summary>
/// Gets the login name for a user alias.
/// </summary>
/// <param name="alias">the user alias (no domain name)</param>
/// <returns>the DOMAINalias string</returns>
private static string GetLoginName(string alias)
{
    NTAccount nt = new System.Security.Principal.NTAccount(alias);
    SecurityIdentifier sid = (SecurityIdentifier)nt.Translate(typeof(SecurityIdentifier));
    nt = (NTAccount)sid.Translate(typeof(NTAccount));
    return nt.Value;
}

Last but not least, try using the SPUtility methods such as IsLoginValid, ResolvePrincipal, and SearchPrincipals.

About Dan Parker

SharePoint Developer since 2007. Born and raised in northern California, and moved to Houston in 2006. Always looking to improve my skills in SharePoint and .NET development.

Posted on March 11, 2009, in SharePoint. Bookmark the permalink. 2 Comments.

  1. Good article.

  2. Hello!
    Very nice article. I worked with EnsureUser and faced with problems you described. Eventually, I’ve developed a small method-wrapper for EnsureUser. It’s shown in my blog – http://dotnetfollower.com/wordpress/2011/05/sharepoint-wrapper-over-ensureuser/
    Thanks!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.