Claims Tips 1: Learning About Claims-Based Authentication in SharePoint 2010
Summary: Learn five tips related to claims-based authentication in SharePoint 2010.
Last modified: August 12, 2011
Applies to: Business Connectivity Services | Open XML | SharePoint Designer 2010 | SharePoint Foundation 2010 | SharePoint Online | SharePoint Server 2010 | Visual Studio
In this article
Overview of the Scope of This Article
Tip 1: Creating Multiple Claims Authentication Web Applications in a Single SharePoint 2010 Farm
Tip 2: Migrating a Web Application from Windows Classic to Windows Claims in SharePoint 2010
Tip 3: Using Audiences with Claims Authentication Sites in SharePoint 2010
Tip 4: Creating an Identity Role and a Role Claim for a SharePoint 2010 Claims Authentication Application
Tip 5: Determining What Claims You Have in SharePoint 2010
Provided by: Steve Peschka, Microsoft Corporation
Download the code sample that accompanies this article: SharePointClaims_MSDNExample.zip
This article provides tips for and answers to frequently asked questions related to claims-based authentication in Microsoft SharePoint 2010. It also provides tips and guidance to help solve problems related to using and configuring claims, and points to other resources for more information.
The code sample that accompanies this article, SharePointClaims_MSDNExample.zip, is for Tip 5: Determining What Claims You Have in SharePoint 2010.
The primary point of confusion about how to configure multiple web applications that use claims authentication in SharePoint 2010 is around the SPTrustedIdentityTokenIssuer object. As I noted in the blog entry Planning Considerations for Claims Based Authentication in SharePoint 2010, you can associate a token-signing certificate only from a security token service (STS) with one SPTrustedIdentityTokenIssuer object. When you create your SPTrustedIdentityTokenIssuer object, you tell the SPTrustedIdentityTokenIssuer object:
The token signing certificate that you are using.
The realm that you are using.
The realm is important because it is included in the query string that is sent back to your STS. Your STS uses that realm to figure out which relying part you are, so that STS knows what claim rules to process, the URL it should use to look up the trust policy for the web application, and so on. Even though you can add multiple token signing certificates to something like Active Directory Federation Services (AD FS) 2.0, there is no way to say a particular token signing certificate should be used with a particular relying party, so you really need to find a way to make it work with the single certificate.
The SPTrustedIdentityProvider object has a ProviderRealms property that takes multiple realms. For example, you have two web applications: https://collab and https://mysites. You use Windows PowerShell to create a SPTrustedIdentityTokenIssuer that looks something like the following cmdlet snippet.
$realm = "urn:sharepoint:collab" $ap = New-SPTrustedIdentityTokenIssuer -Name "ADFS v2" -Description "ADFS v2" -Realm $realm -ImportTrustCertificate $cert -ClaimsMappings $map -SignInUrl "https://URLToYourAdfsServer/adfs/ls" -IdentifierClaim http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
The SPTrustedIdentityTokenIssuer object is now created and has a default realm of urn:sharepoint:collab. We create a relying party in AD FS 2.0 and tell it that the identifiers are urn:sharepoint:collab and https://collab/_trust/. Now, to support our second web application, we need to add another realm to our SPTrustedIdentityTokenIssuer object. The following is the Windows PowerShell code for that.
$uri = new-object System.Uri("https://mysites") $ap.ProviderRealms.Add($uri, "urn:sharepoint:mysites") $ap.Update()
The key thing to understand here is the URI. The URI should be the URL to the web application that will use that realm. During authentication, SharePoint does a lookup to find the realm that is associated with the URI of that web application; that will be the URI that SharePoint uses. In this case, we want the realm urn:sharepoint:mysites to be used with the web application at https://mysites, so we plugged in that URI when we added the realm. Now we can go back to AD FS 2.0 and define a second relying party with an identifier of urn:sharepoint:mysites and https://mysites/_trust/ and everything should just work.
What do I do if I have a web application that is using Windows classic authentication and I want to change it to use Windows claims authentication? It could be that you started in Windows classic and now want to move to claims authentication, or maybe you had a SharePoint 2007 site that you upgraded. I did this in a relatively small test case and wanted to share the process and things I looked at.
After you move to Windows claims, you cannot go back to Windows classic. Ensure that you have good backups before you start; I backed up my content database in Microsoft SQL Server and my web application in Central Administration. I strongly recommend that you try this in a lab first before moving into production.
Now, with our caveats out of the way, the process itself is fairly straightforward. A few lines of Windows PowerShell code and a little time should get you there. The following are the Windows PowerShell commands.
$WebAppName = "http://yourWebAppUrl" $account = "yourDomain\yourUser" $wa = get-SPWebApplication $WebAppName Set-SPwebApplication $wa -AuthenticationProvider (New-SPAuthenticationProvider) -Zone Default #This causes a prompt about migration. Click Yes and continue. #The following step sets the user as an administrator for the site. $wa = get-SPWebApplication $WebAppName $account = (New-SPClaimsPrincipal -identity $account -identitytype 1).ToEncodedString() #After the user is added as an administrator, we set the policy so that the user can have the correct access. $zp = $wa.ZonePolicies("Default") $p = $zp.Add($account,"PSPolicy") $fc=$wa.PolicyRoles.GetSpecialRole("FullControl") $p.PolicyRoleBindings.Add($fc) $wa.Update() #The final step is to trigger the user-migration process. $wa = get-SPWebApplication $WebAppName $wa.MigrateUsers($true)
A few things might still be problems for you, after implementing the previous commands:
Users cannot log on. You may find that users cannot log on to the site. After entering your credentials, you may be notified that you are the domain\user, but that you do not have access rights. If you see this message, it is likely that you have configured the portalsuperuseraccount property and the portalsuperreaderaccount property of the web application prior to migration. You must update them to use the new claims-based account name. You can get the new claims-based account name by looking at the web application policy for the web application after migration; copy the account name from there.
Existing alerts may not fire. Currently, if existing alerts do not fire, the only workaround that I have seen is to delete and recreate the alerts.
Search crawl does not function. Double-check the web application policies and ensure that the search crawl account shows the new converted account name. If it does not, you must manually create a new policy for the crawl account.
In addition, the MigrateUsers cmdlet runs in a timer job, so you may need to wait for it to complete. After I was finished, I verified the following:
Users can log on. Users who are added individually and users who are part of an Active Directory group that had been added to a SharePoint group can log on.
The My Tasks view of a task list still works. Items that were assigned to me as a Windows classic authenticated user are still showing up in My Tasks (that is, it understands that "Windows claims Steve" used to be "Windows classic Steve").
My approval workflows that were in process still work. I am still able to complete the approval workflows successfully.
My custom SharePoint Designer workflows that were in process still work. I am still able to complete my custom workflows successfully.
I can create SharePoint Designer workflows. I am able to create new instances of default workflows and custom SharePoint Designer workflows.
I can crawl the web application. I am able to successfully crawl the web application.
I can query content. I am able to successfully query the contents from crawling the web application.
I have noticed one anomaly so far—when I create a new alert in the site, it says it is created successfully (I even get an email message telling me that it did so), but when I go to manage my alerts, it does not show up in the list. Also, changes do not generate an alert email message. If I find other anomalies, I will try to update this on my blog.
Something that you may not have thought of about using Security Assertion Markup Language (SAML) claims is the effect on the audiences feature in SharePoint 2010. By default, we import users only from directories like Active Directory and a few Lightweight Directory Access Protocol (LDAP) sources.
The problem is that the account name for most SAML claims users is something like i:05:t|adfs with email@example.com. So, can you use audiences with these claims users? The answer is yes, fortunately, but you need to do some work.
The first and most important thing is that you will need to create profiles for these people. You can create the profiles manually or you can write some code to do it. But you need to create these profiles and use the like i:05:t|adfs with firstname.lastname@example.org string as the account name, and then populate the other fields with data that you want to use in your audiences.
Next, create new audiences. You will not be able to use a user-based audience, like member of a group (at least not without writing more code, which is beyond what I discuss here). Instead, you use the property-based audience. In my scenario, I used the Office field from the profile as the basis for my audience. I created two profiles for two different claims users and gave one an Office field of Contoso and one an Office field of Wingtip Toys. So, in my new audience, I created a rule where Office = Contoso and named it Contoso Employees. After I compiled my audience, I could see that its membership included my claims user.
To further validate it, I then went into my claims site and targeted a Web Part at an audience. The only thing that was a little unexpected is that the People Picker was not properly populated with a list of all the audiences. However, when I searched for Contoso Employees, it did find the audience that I created. I selected that audience for the Web Part targeting and saved my changes. Finally, I navigated to the site as my two different claims users. The user that was part of the Contoso Employees audience saw the part, while the other did not.
For various reasons, getting a claims-based authentication web application up and working correctly with both an identity claim and a role claim has been troublesome. So here, I am going to share the steps just for creating the claims and the SPTrustedIdentityTokenIssuer object.
Create the identity claim, as shown in the following code.
Create the role claim, as shown in the following code.
Include both claims when creating your SPTrustedIdentityTokenIssuer object, as shown in the following code.
$ap = New-SPTrustedIdentityTokenIssuer -Name "ADFS v2" -Description "ADFS v2" -Realm "yourRealmName" -ImportTrustCertificate $yourCert -ClaimsMappings $map,$map2 -SignInUrl "https://URLToYourAdfsServer/adfs/ls" -IdentifierClaim "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
One of the keys here is that you need to include both claims when you create your token issuer; you cannot add it afterward. This is one of the limitations of SPTrustedIdentityTokenIssuers.
One of the interesting problems I was working on had to do with some strange permissions errors on a claims authentication site. Part of the difficulty in troubleshooting the situation is that we are not enumerating the claims that SharePoint thinks we have and dumping them out anywhere.
So when I went to a site and either got an access denied error or did not have access to all of the content that I thought I should, I did not have a good way to determine why that is the case. To help debug those types of scenarios, I wrote a fairly simple piece of code to tell me what claims SharePoint has for me, that is, the current user request. I implemented this in two ways.
One part of the assembly is implemented as an HttpModule. It enumerates the claims and then outputs them to the Unified Logging Service (ULS) log. You can easily find these entries by filtering the ULS log on the category SharePoint Claims Enumeration. The HttpModule is useful for cases where you are not even able to log into the site.
The second part of the assembly is implemented as a Web Part. It just emits the claims that you have and the value for each claim. That is useful in a scenario where you can log on to the site, but you are trying to troubleshoot why you do not have access to all of the content that you think you should.
The code sample for this article, SharePointClaims_MSDNExample.zip, contains the source code and debug version of this assembly; read the Instructions.txt file to see instructions.
One other important thing that I learned about claims in SharePoint is that, after you authenticate to your STS, your token comes back to SharePoint. SharePoint has a list of all the claims that it is expecting to see—it looks for all of those and builds them into an SPClaim object. If your STS sends back other claims in addition to what SharePoint is expecting, SharePoint ignores those additional claims and they are not added to the SPClaim object. This might be useful to remember when trying to troubleshoot claims authentication issues.
For more information, see the following resources: