Share-n-dipity

SharePoint serendipity is the effect by which one accidentally discovers something fortunate, especially while looking for something else entirely. In this case, it is the occassional musings, observations, and Ouija board readings about the phabulously

Writing a Custom Claims Provider for SharePoint 2010 - Part 2: Adding Support for Hierarchy Nodes

Writing a Custom Claims Provider for SharePoint 2010 - Part 2: Adding Support for Hierarchy Nodes

  • Comments 7
  • Likes

In Part 1 of this series we showed how to create a custom claims provider, and how to do claims augmentation.  In part 2 were going to show a simple way to add a hierarchy to the people picker control.  In and of itself this isn't necessarily interesting, but when we get to part 3 you'll see how we can use that.  So we'll go back to our class that we created for part 1, and we're going to need to touch 1 property and 1 method:  SupportsHierarchy and FillHierarchy.

SupportsHierarchy is simply a property, and we now want to return true so that SharePoint knows we can fill a hierarchy up.  So that property simply looks like this:

public override bool SupportsHierarchy

{

      get

      {

            return true;

      }

}

 

Once we set that to true, then our FillHierarchy method will be called by SharePoint when the people picker is displayed.  When we add a node to the hierarchy we need to provide a display name and node ID.  To help with that and correspond to the favorite basketball teams we've been using, I created a couple of simple helper arrays to keep track of label names and IDs.  Here's what they look like; in case you've forgotten from the first posting I'll also show the array of team names we use for our favorite teams:

//teams we're using

private string[] ourTeams = new string[] { "Blazers", "DVK Jovenut", "Shanghai Tigers" };

 

//keys for our picker hierarchy

private string[] teamKeys = new string[] { "empUS", "empEMEA", "empASIA" };

 

//labels for our nodes in the picker

private string[] teamLabels = new string[] { "US Teams", "European Teams", "Asian Teams" };

 

Okay, so now that we know what our keys and labels are, I'll show you the FillHierarchy method that I use to add the nodes when the picker is displayed.  As I was saying, this is really more for demonstration purposes, I don't have a great reason to do it from a functional perspective for this particular scenario. 

One thing that is important to note here - if you are NOT creating identity claims, then a claim can be used to provision almost any security item in a SharePoint site except for a site collection administrator.  Fortunately we do get a clue when a search is being performed for a site collection admin.  When that happens, the entityTypes array will only have one item, and it will be "Users".  In all other circumstances you normally see at least six items in the entityTypes array.  If you are the default claims provider for an SPTrustedIdentityTokenIssuer then you do issue identity claims, and so you can assign one of your identity claims to the site collection administrator.  In this case since this provider is not an identity provider, we will add a special check when we fill the hierarchy because we don't want to add a hierarchy we know we'll never use.

protected override void FillHierarchy(Uri context, string[] entityTypes,

      string hierarchyNodeID, int numberOfLevels,

      Microsoft.SharePoint.WebControls.SPProviderHierarchyTree hierarchy)

{                       

//make sure picker is asking for the type of entity we

//return; site collection admin won't for example

if (!EntityTypesContain(entityTypes, SPClaimEntityTypes.FormsRole))

      return;

 

//check to see if the hierarchyNodeID is null; it will be when the control

//is first loaded but if a user clicks on one of the nodes it will return

//the key of the node that was clicked on.  This lets you build out a

//hierarchy as a user clicks on something, rather than all at once.  So I

//wrote the code for that scenario, but I'm not using it in that way. 

//Which just means that I could have just as easily done an

//if (hierarchyNodeID == null) in this particular implementation rather

//than a switch statement

switch (hierarchyNodeID)

{

      case null:

            //when it first loads add all our nodes

            hierarchy.AddChild(new

                  Microsoft.SharePoint.WebControls.SPProviderHierarchyNode(

                  SqlClaims.ProviderInternalName,

                  teamLabels[0],

                  teamKeys[0],

                  true));

 

            hierarchy.AddChild(new

                  Microsoft.SharePoint.WebControls.SPProviderHierarchyNode(

                  SqlClaims.ProviderInternalName,

                  teamLabels[1],

                  teamKeys[1],

                  true));

 

            hierarchy.AddChild(new

                  Microsoft.SharePoint.WebControls.SPProviderHierarchyNode(

                  SqlClaims.ProviderInternalName,

                  teamLabels[2],

                  teamKeys[2],

                  true));

            break;

      default:

            break;

} 

}

 

So that's all there is too it - I'm just checking to see if the hierarchyNodeID is null, which it always is the first time the control loads.  If it is then I add my nodes to the tree in the left pane.  To get this code functional I just compile my assembly again, add it back into the GAC, and do an IISRESET.  Then I can hit the site and try modifying permissions to bring up the people picker.  Here's what the picker actually looks like now after implementing this code:

Now there is one thing worth pointing out here too.  For those of you that are following closely, you may wonder why the people picker shows my claim provider name as "Steve's SQL Claims Provider" rather than the Name property you saw in the code - "Basketball Teams".  Well, simply stated, I'm lazy.  What you see for the name is what I originally called my provider.  As I fleshed out the scenario more I decided to change the name but didn't go through all the hoops <grin> to get it updated in the claims provider list.  So that's why you see that name there.

That's all for this post.  In part 3 we'll look at how to actually enable searching for claims in the people picker using your custom claims provider.

Comments
  • Would it be possible to write a post with a code sample which demonstrates how to nest 2 or 3 levels deep in the hierarchy?

    Thanks.

  • Steve, i'm at dead-end: i've built a custom claim provider according to your instructions, but when i'm trying to assign permissions to a given claim (like "Blazers"), the PeopleEdit loses the resolved entity when i click the "OK" button. The same thing happens when i use the search funcionality (in the "Select People and Groups" dialog): everything works fine, including the "Add" button, but when i click "OK", the "Select Users" box is empty. On the hand, with regular AD users all is working as expected. Any ideas?

  • Would it be possible to provide a sample custom Claims Provider which demonstrates the usage of the FillHierarchy method in conjunction with consuming Windows Identity Foundation Claims?

    Thanks.

  • Can you provide any details about why a site collection administrator can be picked using a custom claims provider?  Does it have to be from one of the OOTB claims providers like AD?  You are certainly correct that custom providers don't, but I'm just wondering WHY they don't work.  Thanks!

  • Hi,

    Can we show the labels in nested ? And how we can categorize the claims for these labels?

  • Hi Steve,

    I can only seem to return claims in the People Picker that were added by the SPClaimProvider during augmentation, not on any of the incoming claims. Now I'm duplicating the incoming claims in augmentation so users can use them to grant permissions of objects in SharePoint. I was hoping they could directly do this on the incoming claims.

    Cheers,

    Steven

  • thanks

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment