A while ago I posted an entry on how to configure your custom claims provider to replace the out of the box claims provider (http://blogs.technet.com/speschka/archive/2010/04/28/how-to-override-the-default-name-resolution-and-claims-provider-in-sharepoint-2010.aspx). I wanted / need to follow up on that posting, because we found some additional details that you will want to have in hand should you go down this route. If you don’t follow these steps, you may find that the claims you resolve in the search dialog or type-in control don’t map to the account name or other claim that someone logs in with. For some of the reasons why you might want to replace the out of the box provider, see the original blog posting I’ve linked to above.
Now, if you want to replace the out of the box provider and have the account names and claims match what is actually used at login time, there are some additional steps and information you need to be aware of. Here is a quick checklist of rules that I’ve come up with to ensure that my custom claims provider can successfully supplant the out of the box provider. These rules do not cover every type of claims provider scenario – they are the minimum that need to be implemented for this replacement scenario.
IMPORTANT UPDATE - Hi all, I just found out that a few of the methods below changed from when this post was written and when the RTM code was delivered. I have updated this post with the latest info, that I have recently re-verified and have working.
1. The ClaimProviderName of the Get-SPTrustedIdentityTokenIssuer should be the Name of the custom claims provider. Instructions for how to configure this are at http://blogs.technet.com/speschka/archive/2010/04/28/how-to-override-the-default-name-resolution-and-claims-provider-in-sharepoint-2010.aspx.
2. Make sure that the Name property of your custom provider is NOT the same value as the Name property of the Get-SPTrustedIdentityTokenIssuer. You will need the name of the SPTrustedIdentityTokenIssuer when you are creating the claim for the PickerEntity, so I recommend you add another static string property to your custom claim provder that is the name of the SPTrustedIdentityTokenIssuer. For example, here's what I used in my custom claim provider:
internal static string SPTrustedIdentityTokenIssuerName
return "ADFS with Roles";
3. When you create a custom claim provider to replace the out of box provider, you are going to want to override the FillSearch and FillResolve methods. In those overrides you will need to create a PickerEntry instance. Normally for these methods I use the CreateClaim helper method; however, if your provider is going to replace the out of the box provider you do not want to use the CreateClaim helper. Instead you should:
a. Use the new SPClaim constructor.
b. Determine if the claim is an identity claim or not. For example, if the identity claim for the SPTrustedIdentityTokenIssuer is email, then you know that if the claim value is an email address it is an identity claim.
c. For an identity claim, the claimType for the new SPClaim constructor should match the identity claim for your SPTrustedIdentityTokenIssuer. For example, if your identity claim is email, then your claimType parameter should be http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
i. For an identity claim, the EntityType property of the PickerEntity should be SPClaimEntityTypes.User
d. If it is NOT an identity claim, the claimType should be whatever claim makes sense for your application
i. If it is NOT an identity claim, the EntityType property of the PickerEntity should be SPClaimEntityType.WhateverMakesSenseForYourApplication (probably FormsRole in many cases)
e. For the last parameter of the new SPClaim constructor, use the following: SPOriginalIssuers.Format(SPOriginalIssuerType.TrustedProvider, SPTrustedIdentityTokenIssuerName)
f. Here’s an example of an identity claim with all of these pieces put together:
myPickerEntity.Claim = new SPClaim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", "email@example.com", Microsoft.IdentityModel.Claims.ClaimValueTypes.String, SPOriginalIssuers.Format(SPOriginalIssuerType.TrustedProvider, SPTrustedIdentityTokenIssuerName));
IMPORTANT NOTE: If you are the default claims provider for an SPTrustedIdentityTokenIssuer, you should use this method to create the PickerEntity claim irrespective of the type of claim; meaning, use this method whether it's an identity claim, role claim, etc.
So the key takeaways from this should be:
1. Add a new property to your claim provider that is the name of the SPTrustedIdentityTokenIssuer where the provider will be used.
2. When you are resolving an identity claim, make sure the EntityType is SPClaimEntityTypes.User
3. Don’t use the CreateClaim helper method; use the new constructor for an SPClaim
4. For the last parameter of the SPClaim constructor, use the SPOriginalIssuerType enum.
I’ve tested this in my environment and have it working successfully, and I’ve also worked with one of our MVP’s who was able to make it work for his customer following this same set of rules.
so what about the following scenario:
- We have a seperate WIF STS for authentication for all our users.
- We configured this STS as our SPTrustedIdentityTokenIssuer in Sharepoint.
- This STS only delivers the userid. The user attributes (claims) come from two different backends:
internal users are in one DB, guest users are in the other DB (userid from STS clearly distincts which DB to query) and so we would like to have two different ClaimProviders (or even more later). Both types of users authenticate to the same STS.
So what should we set for ClaimProviderName property of our SPTrustedIdentityTokenIssuer?
in short: how to configure one STS with several ClaimProviders?
Adding additional claims from multiple stores is the role of claims augmentation, which you can also do with a custom claims provider. I would write one or more claims providers that only do claims augmentation and retrieve your custom claim info from the database in it.
All your posts have been very helpful. I have configured SharePoint 2010 with ADFS 2.0 and i even got the user profiles mapped to the ADFS claims
I still have an issue with the picker. I have read all your posts about the naming resolution and creating a custom claim provider and it's excellent for setting permissions with roles.
But what about assigning a task to an individual user? It requires a unique mapping for a user to be resolved in the picker (username or emailaddress). Is it possible to write a custom claims provider with ldap or should i give it up and stop thinking about web sso and go for ntlm/kerberos claims.
Hi Why would the name property have to match?
If I have a trustedtokenissuer sts I have to name it in your example sqlclaimsprovider?
After reading through I have developed a custom provider that queiries a database and augments the claims (which |I see in the web part and the sts claim email that I authorise against)
How wouold I change the people picker to search on the email as I do not augment this claim in the custom provider?
Thanks for all your post they are absolutely fantastic, and I have recently implemented the End-to-End adfs in a production environment, but is in the same boat as Marc Van Eijk was about the User profile and claims but cannot seem to get his link to work for me.
Marc, could you please update that link so i can use your solution as well?
Not sure if you check this as it's an old post but here's hoping.
I followed your excellent posts to create a custom claims provider.
Everything works (the user claims get properly resolved and I can add them to groups) until I set it to replace the default provider for my token issuer. At this point the claims are still resolved but clicking OK to add the user to a specific groups causes an error (user may not exist or is not unique).
Have you seen this before or know where I might be going wrong?
I've also put a post up in the forums to see if anyone else ran into this.
Thanks for any help you can give.
thank you for this Blog. For me the most valuable Information on Claims and Sharepoint.
Is there an easy way to revert back to the empty default ClaimProviderName with Powershell?
$trusted.ClaimProviderName = “” or $trusted.ClaimProviderName=$Null
are not accepted. (Claims Provider does not exist)
The Web Application in my testing environment responds with error "0x8107058a ....not set to an instance of an object" if the Claims Provider is deactiveated.
Hi Markus, unfortunately that is not possible in this release. Super painful, you have to kill your SPTrustedIdentityProvider and start over. Hopefully they fix this next time around.
Thanks for a great post but i am getting an error whn i run the $trusted.Update() command it throws an error saying the Update() command cannot run with 0 arguments, can you suggest how to rectify this issue.
Thanks for the great series on Custom Claims Providers!
I have really stumped Microsoft with a couple of posts to the Partner forums pretaining Custom Claim Providers. I have duplicated these posts to the public forums as well. I was wondering if you could review my posts and provide feedback to my posts.
SharePoint 2010 Custom Claims Provider - How to display AD Groups/SharePoint Roles
SharePoint 2010 People Picker Behavior with ADFS20 Custom Claims Provider
SharePoint 2010 User Display issues when using ADFS20 Custom Claim Provider
Any advice/insight you can provide would be greatly appreciated!
@Markus, it's actually possible to revert back to the default claim provider by using reflection, like this:
$ip = Get-SPTrustedIdentityTokenIssuer XXXX