I have been working with claims authentication quite a bit lately, and something that can be frustrating when using claims authentication for Forms Based Authentication (FBA) or SAML claims is that when you log in you see the claims identifier instead of the user’s name. As an example, I configured an FBA provider to use LDAP to authenticate users and when I log in, I see the following:
Similarly, I configured a trusted provider using ADFS and when I log in as a user using SAML claims, the user’s name is shown as the following:
This is because the user profile for the user has not been populated. In my environment, I have 3 providers configured for the same zone.
To understand how to configure the trusted identity provider, see Steve Peschka’s post Configuring SharePoint 2010 and ADFS v2 End to End. To understand how to configure FBA, see my posts SQL Server Provider for FBA in SharePoint 2010, configuring FBA with SqlMembershipProvider in SharePoint 2010 using PowerShell, and Configuring LDAP for FBA in SharePoint 2010 or SharePoint 2013 with PowerShell.
This post is going to show how to configure user profile synchronization when you have multiple authentication providers. In my scenario, all of the users are being imported from the same Active Directory instance. This provides a challenge for using apps. Working with apps in SharePoint 2013 requires user profiles to be populated (see Steve Peschka’s article, “OAuth and the Rehydrated User in SharePoint 2013 – How’d They do That and What do I Need to Know”). It becomes increasingly important in SharePoint 2013 to properly configure the user profiles with UPN, Email, or SIP attributes when working with apps. It doesn’t matter how you populate these, you could use PowerShell or a custom program, but SharePoint provides the ability to populate these attributes using User Profile Synchronization. The challenge is that apps will rehydrate the user typically based on email, so the email has to be unique across all of the user profiles. This makes it important to make sure that each user in your directory has exactly one profile in SharePoint.
Steve Peschka did a great job showing how to accomplish this in his blog Mapping User Profiles for SAML Users with an AD Import in SharePoint 2013. The part I want to highlight is how to configure multiple sync connections.
Multiple Synchronization Connections
In my scenario, I have 3 different connections to the same Active Directory.
The challenge here is making sure that your users do not overlap and that they are unique per connection. If you have a user that is imported from AD and authenticates both as a Windows user and as a SAML user, the authentication for apps will likely fail because you cannot uniquely identify the user based on email. This is why it is important to make sure that each user account has a unique profile.
Configuring Multiple Connections for User Profile Synchronization
I am not going into the details of how to start the user profile synchronization service instance. For details, see Spence Harbar’s seminal post Rational Guide to implementing SharePoint Server 2010 User Profile Synchronization. The steps are identical for SharePoint 2013. The part we are going to focus on is configuring the connections for our scenario that includes multiple connection sources.
Configuring a Connection for Active Directory
This is the best-documented and easiest to configure because you only need to configure the connection and you’re done. Spence covers the details in his blog post Rational Guide to implementing SharePoint Server 2010 User Profile Synchronization. Even though we are authenticating with Windows claims, the only thing you need to do is configure user profile synchronization to Active Directory.
The important thing to watch out for is that you import only the users who will log in via Windows. I have an OU called “Employees” in Active Directory that contains all of my users who authenticate via Windows to avoid overlap.
When configuring the user profile synchronization connection, I choose only this OU.
Click OK and you’re done.
Configuring a Connection for FBA
My FBA implementation is using LDAP, which points to Active Directory to authenticate the users. Because I am using Active Directory as the LDAP provider for FBA, I can import the users with a connection to Active Directory with one special change. The key is to set the Authentication Provider Type to Forms Based Authentication, and choose the FBA provider that you’ve already configured (this value is picked up from the web.config in Central Administration).
To make sure that the account does not have multiple profiles, I constrain the synchronization to a specific OU that contains only those users who authenticate via LDAP.
Once you have configured the connection, the next step is to map the claim identifier. Go to the User Profile Service Application and click on User Profile Properties. Edit the property “Claim User Identifier” and add a mapping for the attribute that will be used to identify the user via claims.
Setting the authentication provider type, selecting the FBA provider, and mapping the claim identifier is important because this is used to map the claims encoded account name. Once the user is imported, you can see the claims encoded account name to identify the user.
If you see two profiles for the same user, the problem might be because you didn’t map the provider type on the connection, or didn’t add the mapping for the claims identifier.
Configuring a Connection for a Trusted Identity Provider
I am using ADFS to authenticate my users. When I use user profile sync, I am not connecting to ADFS, I am connecting to the Active Directory where the users are authenticated to. I can sync the users to that Active Directory to populate their attributes. As mentioned several times earlier, I need to make sure that the user profiles are unique. To ensure this, I have a single OU for the users who authenticate via ADFS.
I then set up a user profile sync connection to Active Directory. Just like when we configured FBA, we need to specify the Authentication Provider Type (this time we choose “Trusted Claims Provider Authentication”), and the Authentication Provider Instance (which is the name of the trusted identity provider you’ve already configured).
To make sure that these users do not have multiple profiles, I import them from an OU where only those users authenticate via ADFS.
The next step is to go to the user profile properties and add a mapping for the Claim User Identifier. Note that when you have multiple connections, you will need to map each individually. I could have the FBA users mapped using sAMAccountName instead of mail, I just chose to map them using the mail attribute since all my users have an email address. Edit the property Claim User Identifier and add a mapping.
The claim identifier that you map for the ADFS connection needs to be the same attribute that you specified in the IdentifierClaim parameter when registering the SPTrustedIdentityTokenIssuer.
$ap = New-SPTrustedIdentityTokenIssuer -Name "SAML Provider" -Description "SharePoint secured by SAML" -realm $realm -ImportTrustCertificate $cert -ClaimsMappings $map,$map2 -SignInUrl "https://congen1.contoso.local/adfs/ls" -IdentifierClaim "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
See Steve Peschka’s blog Configuring SharePoint 2010 and ADFS v2 End to End for more information on configuring ADFS.
One other side note… when you are adding users to your site that are SAML users, take care to use the same identifierclaim when adding them as a user to a site. I type the full email, and then make sure I select the EmailAddress claim. If you want to change this behavior, see Steve Peschka’s blog for creating custom claims providers. The user will show as the IdentifierClaim until the user profile is updated with their name.
What if My User Doesn’t Come From Active Directory?
FBA users are a little more difficult because you may be using SQL for FBA, in which case there’s really no option for user profile synchronization out of the box, you need to update it through some other means. Additionally, you might be authenticating to a trusted provider where you cannot sync all the users from the source into user profiles. Luckily it’s pretty easy to update via using the object model, which can be accessed via PowerShell or C#.
$mySiteUrl = "http://my.contoso.lab" $gc = Start-SPAssignment $site = ($gc | Get-SPSite $mySiteUrl) $context = ($gc | Get-SPServiceContext -Site $site) $upm = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($context) $profile = $upm.GetUserProfile("i:firstname.lastname@example.org"); $profile["WorkEmail"].Value = "email@example.com"; $profile.Commit() Stop-SPAssignment $gc
Other properties that you might want to map are SIP (mapped to the SharePoint property “SPS-SipAddress”) or the UPN (mapped to the SharePoint property “SPS-UserPrincipalName”). The important point to note here is that it doesn’t matter if you use user profile sync or if you populate the attributes through some other process, the part that matters is that the properties are populated for the user. You could also provide the user’s name while you’re at it to provide a friendly name at the top right of the screen.
Showing The User Name
This blog started off showing the problem of claims users not showing their name in the top right of the page when they log in. The only thing you have to do is make sure that their name is populated in the user profile, either through sync or through your own process. To prove this, the same user that used to show the email now shows their name instead.
The name is displayed as part of their user profile, so you can take advantage of the fact that apps require a populated user profile and simply populate the name as part of your sync process.