Export (0) Print
Expand All

Sample 2: Writing a Claims Provider

SharePoint 2010

Last modified: August 03, 2010

Applies to: SharePoint Foundation 2010

The following sample shows how to write a claims provider. This sample implementation supports entity, resolve, and search, but not hierarchy. You can find a code example that shows how to support hierarchy in the reference topic for the FillHierarchy() method of the SPClaimProvider class.

To write a claims provider, your first step is to create a class that derives from the SPClaimProvider class. This topic assumes that you have read the How to: Create a Claims Provider topic.

For more information about creating a claims provider and for a walkthrough, see Claims Walkthrough: Writing a Claims Provider.

Tip Tip

For an additional code example and more information about the SPClaimProvider class and its members, see SPClaimProvider. Also, check the SharePoint SPIdentity Team Blog and the Share-n-dipity blog regularly for additional samples and updates.

Sample code provided by: Andy Li, Microsoft Corporation.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration.Claims;
using Microsoft.IdentityModel.Claims;
using System.Collections;
using Microsoft.SharePoint.WebControls;

namespace ContosoClaimProviders
{
    public class CRMClaimProvider : SPClaimProvider
    {

        public CRMClaimProvider(string displayName)
            : base(displayName)
        {
        }

        public override string Name
        {
            get { return "ContosoCRMClaimProvider"; }
        }

        /// <summary>
        /// Must return true if you are doing claim augmentation.
        /// </summary>
        public override bool SupportsEntityInformation
        {
            get { return true; }
        }

        /// <summary>
        /// Return true if you support claim resolve in the People Picker control.
        /// </summary>
        public override bool SupportsResolve
        {
            get { return true; }
        }

        /// <summary>
        /// Return true if you support claim search in the People Picker control.
        /// </summary>
        public override bool SupportsSearch
        {
            get { return true; }
        }

        /// <summary>
        /// Return true if you support hierarchy display in the People Picker control.
        /// </summary>
        public override bool SupportsHierarchy
        {
            get { return false; }
        }

        public override bool SupportsUserSpecificHierarchy
        {
            get
            {
                return base.SupportsUserSpecificHierarchy;
            }
        }

        /// <summary>
        /// Implement this method if the claims provider supports claim augmentation.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="entity"></param>
        /// <param name="claims"></param>
        protected override void FillClaimsForEntity(Uri context, SPClaim entity, List<SPClaim> claims)
        {
            if (null == entity)
            {
                throw new ArgumentNullException("entity");
            }
            if (null == claims)
            {
                throw new ArgumentNullException("claims");
            }

            //Adding the role claim.
            SPClaim userIdClaim = SPClaimProviderManager.DecodeUserIdentifierClaim(entity);

            //Adding claims for user.
            List<string> allCRMUsers = CRMUserInfo.GetAllUsers();
            
            if(allCRMUsers.Contains(userIdClaim.Value.ToLower()))
            {
                List<Claim> userClaims = CRMUserInfo.GetClaimsForUser(userIdClaim.Value.ToLower());
                foreach(Claim claim in userClaims)
                {
                    claims.Add(CreateClaim(claim.ClaimType, claim.Value, claim.ValueType));
                }

            }

        }

        /// <summary>
        /// Returns all the claim types that are supported by this claims provider.
        /// </summary>
        /// <param name="claimTypes"></param>
        protected override void FillClaimTypes(List<string> claimTypes)
        {
            if (null == claimTypes)
            {
                throw new ArgumentNullException("claimTypes");
            }

            // Add the claim types that will be added by this claims provider.  
            claimTypes.Add(CRMClaimType.Role);
            claimTypes.Add(CRMClaimType.Region);
        }

        /// <summary>
        /// Return all claim value types that correspond to the claim types.
        /// You must return the values in the same order as in the FillClaimTypes() method. 
        /// </summary>
        /// <param name="claimValueTypes"></param>
        protected override void FillClaimValueTypes(List<string> claimValueTypes)
        {

            if (null == claimValueTypes)
            {
                throw new ArgumentNullException("claimValueTypes");
            }

            claimValueTypes.Add(Microsoft.IdentityModel.Claims.ClaimValueTypes.String);
            claimValueTypes.Add(Microsoft.IdentityModel.Claims.ClaimValueTypes.String);
        }

        /// <summary>
        /// Required for People Picker. This tells the People Picker what 
        /// information is available for the entity.
        /// </summary>
        /// <param name="schema"></param>
        protected override void FillSchema(SPProviderSchema schema)
        {
            schema.AddSchemaElement(new SPSchemaElement(PeopleEditorEntityDataKeys.DisplayName,
                                                        "DisplayName",
                                                         SPSchemaElementType.TableViewOnly));
        }

        /// <summary>
        /// Returns the entity type for the claims returned from the claims provider.
        /// </summary>
        /// <param name="entityTypes"></param>
        protected override void FillEntityTypes(List<string> entityTypes)
        {
            entityTypes.Add(SPClaimEntityTypes.FormsRole);
            entityTypes.Add(SPClaimEntityTypes.FormsRole);
        }


        /// <summary>
        /// Required if you implement the claim search for the People Picker control.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="entityTypes"></param>
        /// <param name="searchPattern"></param>
        /// <param name="hierarchyNodeID"></param>
        /// <param name="maxCount"></param>
        /// <param name="searchTree"></param>
        protected override void FillSearch(Uri context, string[] entityTypes, string searchPattern, string hierarchyNodeID, int maxCount, SPProviderHierarchyTree searchTree)
        {
            string keyword = searchPattern.ToLower();
            Hashtable knownClaims = CRMUserInfo.GetAllClaims();
            List<string> knownClaimsList = new List<string>();

            //Convert the knownClaims.Key into a List<string> for LINQ query.
            foreach (string claim in knownClaims.Keys)
            {
                knownClaimsList.Add(claim);
            }
            

            var claimQuery = knownClaimsList.Where(claim => claim.IndexOf(keyword) >= 0).Select(claim => claim);

            foreach (string claimValue in claimQuery)
            {
                //Get the claim type.
                //For example, if you are search "SalesManager", the ClaimType will be 
                //CRMClaimType.Role

                string claimType = CRMUserInfo.GetClaimTypeForRole((string)knownClaims[claimValue]);

                PickerEntity entity = CreatePickerEntity();
                entity.Claim = CreateClaim(claimType, claimValue, Microsoft.IdentityModel.Claims.ClaimValueTypes.String);
                entity.Description = claimValue;
                entity.DisplayText = claimValue;
                entity.EntityData[PeopleEditorEntityDataKeys.DisplayName] = claimValue;
                entity.EntityType = SPClaimEntityTypes.FormsRole;
                entity.IsResolved = true;
                searchTree.AddEntity(entity);
            }

        }

        /// <summary>
        /// Resolve one single claim by using exact match. This method is required for both 
        /// claim search and resolve.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="entityTypes"></param>
        /// <param name="resolveInput"></param>
        /// <param name="resolved"></param>
        protected override void FillResolve(Uri context, string[] entityTypes, SPClaim resolveInput, List<PickerEntity> resolved)
        {
            string keyword = resolveInput.Value.ToLower();
            Hashtable knownClaims = CRMUserInfo.GetAllClaims();

            if (knownClaims.ContainsKey(keyword))
            {
                //Get the claim type.
                //For example, if you are search "SalesManager", the ClaimType will be 
                // CRMClaimType.Role. In this case, the keyword is the value of the claim.
                string claimValue = keyword;
                string claimType = CRMUserInfo.GetClaimTypeForRole((string)knownClaims[keyword]);

                PickerEntity entity = CreatePickerEntity();
                entity.Claim = CreateClaim(claimType, claimValue, Microsoft.IdentityModel.Claims.ClaimValueTypes.String);
                entity.Description = claimValue;
                entity.DisplayText = claimValue;
                entity.EntityData[PeopleEditorEntityDataKeys.DisplayName] = claimValue;
                entity.EntityType = SPClaimEntityTypes.FormsRole;
                entity.IsResolved = true;
                resolved.Add(entity);
            }
        }


        /// <summary>
        /// Required if you implement claim resolve for the People Picker control.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="entityTypes"></param>
        /// <param name="resolveInput"></param>
        /// <param name="resolved"></param>
        protected override void FillResolve(Uri context, string[] entityTypes, string resolveInput, List<PickerEntity> resolved)
        {

            string keyword = resolveInput.ToLower();
            Hashtable knownClaims = CRMUserInfo.GetAllClaims();
            List<string> knownClaimsList = new List<string>();

            //Convert the knownClaims.Key into a List<string> for LINQ query.
            foreach (string claim in knownClaims.Keys)
            {
                knownClaimsList.Add(claim);
            }

            var claimQuery = knownClaimsList.Where(claim => claim.IndexOf(keyword) >= 0).Select(claim => claim);

            foreach (string claimValue in claimQuery)
            {
                //Get the claim type.
                //For example, if you search "SalesManager", the ClaimType will be 
                //CRMClaimType.Role

                string claimType = CRMUserInfo.GetClaimTypeForRole((string)knownClaims[claimValue]);

                PickerEntity entity = CreatePickerEntity();
                entity.Claim = CreateClaim(claimType, claimValue, Microsoft.IdentityModel.Claims.ClaimValueTypes.String);
                entity.Description = claimValue;
                entity.DisplayText = claimValue;
                entity.EntityData[PeopleEditorEntityDataKeys.DisplayName] = claimValue;
                entity.EntityType = SPClaimEntityTypes.FormsRole;
                entity.IsResolved = true;
                resolved.Add(entity);
            }

        }

        protected override void FillHierarchy(Uri context, string[] entityTypes, string hierarchyNodeID, int numberOfLevels, SPProviderHierarchyTree hierarchy)
        {
            throw new NotImplementedException();
        }

        
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ContosoClaimProviders
{
    public class CRMClaimType
    {
        public static string Role = "http://schemas.sample.org/ws/2009/12/identity/claims/CRMRole";
        public static string Region = "http://schemas.sample.org/ws/2009/12/identity/claims/CRMRegion";
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;
using Microsoft.IdentityModel.Claims;
using System.Collections;


namespace ContosoClaimProviders
{
    public class CRMUserInfo
    {
        /// <summary>
        /// A real-world implementation should look up a directory service or database 
        /// to retrieve a user’s claim. 
        /// The code below is used only for demostration purposes.
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public static List<Claim> GetClaimsForUser(string username)
        {
             List<Claim> userClaims = new List<Claim>();
            foreach(string userInfo in userDB)
            {
                string[] claims = userInfo.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries);
                if (username == claims[0])
                {
                    userClaims.Add(new Claim(GetClaimTypeForRole(claims[1]), claims[2], Microsoft.IdentityModel.Claims.ClaimValueTypes.String));
                }
            }

            return userClaims;
        }


        //Manually construct a list of users. In a real-world production environment,
        //you should look up a directory serivce or database to retrieve the user information.
        public static List<string> GetAllUsers()
        {
            List<string> allUsers = new List<string>();
            //Adding Forms users.
            allUsers.Add("bob");
            allUsers.Add("mary");
            allUsers.Add("jack");
            allUsers.Add("admin1");
            //Add Windows domain user, if you want this provider 
            //to support Windows claim mode.
            allUsers.Add("contoso\\myalias");
            return allUsers;
        }

        /// <summary>
        /// This function returns all the known claims from the CRM system so that
        /// the claims provider is able to search and resolve 
        /// the claims in the People Picker control.
        /// </summary>
        /// <returns></returns>
        public static Hashtable GetAllClaims()
        {
            Hashtable knownClaims = new Hashtable();
            foreach(string claimItem in claimsDB)
            {
                string[] claim = claimItem.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries);
                knownClaims.Add(claim[1].ToLower(), claim[0].ToLower());
            }
            return knownClaims;
        }


        public static string GetClaimTypeForRole(string roleName)
        {
            if (roleName.Equals("CRMRole", StringComparison.OrdinalIgnoreCase))
                return CRMClaimType.Role;
            else if (roleName.Equals("CRMRegion", StringComparison.OrdinalIgnoreCase))
                return CRMClaimType.Region;
            else
                throw new Exception("CRM Claim Type not found!");
        }

        private static string[] userDB = 
           {
            "bob:CRMRole:Reader", 
            "bob:CRMRole:SalesRepresentative",
            "bob:CRMRegion:NorthWest",
            "mary:CRMRole:Reader",
            "mary:CRMRole:SalesManager",
            "mary:CRMRegion:East",
            "jack:CRMRole:Reader",
            "jack:CRMRole:Executive",
            "jack:CRMRegion:East",
            "admin1:CRMRole:Administrator",
            "contoso\\myalias:CRMRole:SalesManager"
           };

        private static string[] claimsDB = 
           {"CRMRole:Reader", 
            "CRMRole:SalesRepresentative",
            "CRMRole:SalesManager",
            "CRMRole:Executive",
            "CRMRole:Administrator",
            "CRMRegion:NorthWest",
            "CRMRegion:East",
            };
    }


}

Show:
© 2015 Microsoft