Wednesday, March 16, 2011

Awkward Usernames Courtesy of Claims Authentication (FBA)

Who’s i:0#.f|membership_providerName|userName?

If you’re one of the many people who have set up Forms Based Authentication in SharePoint 2010, you’ve likely enjoyed dealing with the awkward usernames that can come with claims authentication and FBA (Forms Based Authentication).
In a recent engagement, we’d provisioned an ASP.NET Membership schema (aspnet_regsql.exe), populated it with a stock SQLMembershipProvider and then added the users to the site collection using the Site Settings->People and Groups screens.
What we ended up with, were a lot of SPUsers with "unfriendly" SPUser.Name properties set. Since the Name field wasn’t assigned it ended up getting set to the equivalent of the SPUser.LoginName property which looks a lot like:
The problem with leaving these cryptic display names in their native format is that they can seep all over a farm. Not only will they show up in stock SharePoint controls that display user names, but those same display names will also start to show up in other service applications like search.
There's also the fact that your users will likely ask you to set them to something more sensible.

Resting the SPUser.DisplayName Property

Assuming you have some other name that you’d prefer instead of the awkward native claims format, you can explicitly set these display names by using either PowerShell or the stock SharePoint API.
Below are two examples, both involve you iterating over everyone in the authentication store (think SQL, LDAP, AD, etc…) and updating the SPUser.Display/Name property after fetching the SPUser out of the site collection. See below:

$user = Get-SPUser -Web "http://wss2k10tholmes:81" -Identity "i:0#.f|providerName|userName"
$user.DisplayName = "FriendlyName";
C# (API)
//We use ensure so that the given user will be added if they don't exist. They need to be resolved
//via their claims name.
SPUser spUser = web.EnsureUser(string.Format("i:0#.f|providerName|{0}", fbaUser.UserName));
spUser.Name = "FriendlyName";


You don’t necessarily need to go through the API or PowerShell, if you have a connection to an LDAP store or a BCS connection to your auth store. You can also map the properties yourself and leave it to the User Profile Synchronization service. That being said, if you’re dependent on BCS then you’ll also need to have SharePoint Enterprise Server license which isn’t available to all customers.
Once you’re done you should be
Administrator Claims FBA username able to visit any of the users in your site collection and see their “Name” property set to something that is less likely to confuse your user base. Once the value is set, it helps to make sure that it doesn’t get stomped with any User Profile Synchronization (UPS) that may be in place in your farm.

Hope that Helps,