Writing your own Trusted Identity provider for SP2010 (2)

By | 2010-08-31

This is part two of a Multi Blog post on “writing your own Trusted Identity provider / Claim Provider for SP2010“.
In the first post I covered:

In this post I will cover:

Create a Custom SPClaimProvider

For SharePoint 2010 to Trust any Identity Provider, we need a SPClaimProvider specific for that provider. This SPClaimProvider has two main purposes:

  • Provide a way for SharePoint to communicate with any Trusted Identity Provider in a uniform (Interface) way.
  • And provide SharePoint a way to use the same Claims for Users that have logged in through a different (e.g. AD) Identity Provider, let’s call this Claims Augmentation

To create a SPClaimProvider follow the following steps:

  • Create a new VS2010 Empty SP2010 Project
  • And add references to Microsoft.IdentityModel, Microsoft.SharePoint and Microsoft.SharePoint.Security.
  • Create a new Class, let’s name it CustomClaimsProvider and inherit from:Microsoft.SharePoint.Administration.Claims.SPClaimProvider
  • Implement all the methods for resolving claims, this is so we can use the claims provided within SharePoint to give rights to claims:
    • FillHierarchy
    • FillResolve
    • FillSearch, FillSchema
    • FillClaimTypes,FillClaimValueTypes,FillEntityTypes
  • Implement GetClaimsForEntity for the claims augmentation
  • Override the SupportsEntityInformation,SupportsHierarchy,,SupportsResolve and SupportsSearch properties and let them “return True” since we have implemented all the Fill Methods for this SPClaimProvider
  • Give your Provider a Name by overriding the Property Name. You will need this later on.

In fairness, this post has an excellent description on the subject also.
Sample implementation of FillClaimsForEntity

/// <summary>
/// Get's the username part of a claims authentication login claim 
/// figure out who the user is so we know what team to add to their claim
/// the entity.Value from the input parameter contains the name of the 
/// authenticated user.  for a SQL FBA user, it looks something like
/// 0#.f|sqlmembership|user1; for a Windows claims user it looks something
/// 0#.w|stevewilmaf
/// 0#.t|Customsleden|stef@tamtam.nl
/// </summary>
/// <param name="identityClaims"></param>
/// <returns>only the login part</returns>
public static string GetLoginPartFromIdentityClaim(string identityClaims) {
    string login = identityClaims;
    if (!string.IsNullOrEmpty(login) && login.Contains("|")) {
        string[] parts = login.Split('|');
        if (parts.GetLength(0) == 3) // formsbased or trusted provider based
            login = parts[2];
        if (parts.GetLength(0) == 2) // windows based
            login = parts[1];
    }
    return login;
}

/// <summary>
/// Add Claims to a logged in User, from Dynamics CRM info
/// </summary>
/// <param name="context">Current Context, url</param>
/// <param name="entity">the logged in user/claim</param>
/// <param name="claims">The list of claims for the user</param>
protected override void FillClaimsForEntity(Uri context, SPClaim entity, List<SPClaim> claims) {
    if (claims == null)
        throw new ArgumentNullException("claims");
    if (entity == null)
        throw new ArgumentNullException("entity");

    Logging.LogMessage(entity.Value);

    string login = Utilities.GetLoginPartFromIdentityClaim(entity.Value);

    // if windows user, get the email ?
    if (!string.IsNullOrEmpty(login)) {
        Logging.LogMessage(string.Format("User is {0}", login));

        CRMClient.Entities.User user = null;
        string email = login;
        if (login.Contains("@")) {
            user = CRMClient.CrmSQLClient.GetUserByEmail(login);
        }
        if (login.Contains("")) {
            user = CRMClient.CrmSQLClient.GetUser(login);
            if (user != null)
                email = user.Email;
        }
        // employee, crm users
        if (user != null) {
            try {
                Logging.LogMessage(string.Format("User is SystemUser of CRM with an license, Name:{0}", user.FullName));

                claims.Add( GetClaim(CustomClaimsProvider.CustomAccountTypeClaimType, "everyone"));

                SPClaim employee = null;
                if (user.FullLicense) { // admin and or full license                            
                    employee = GetClaim(CustomClaimsProvider.CustomAccountTypeClaimType, "employee");
                }
                else {// readonly 
                    employee = GetClaim(CustomClaimsProvider.CustomAccountTypeClaimType, "employeero");
                }
                if (employee != null)
                    claims.Add(employee);
            }
            catch (Exception exc) {
                Logging.LogException(exc);
            }
        }
        else {
            Logging.LogMessage(string.Format("{0} not found as SYSTEMUSER in CRM", login));
        }
    }
}

Register your Claims Provider for SharePoint

In order for your Claims Provider to be registered within SharePoint 2010 you will need to create a specific type of Feature.

  • Add a Farm Feature to your Project
  • Add an EventReicever to your new Feature
  • And let your receiver inherit from SPClaimProviderFeatureReceiver (see: Register)
  • And now implement the following Properties in your Feature Event Receiver
    • ClaimProviderDisplayName
    • ClaimProviderDescription
    • ClaimProviderAssembly
    • ClaimProviderType

You can use this to return the last two properties:

/// <summary>Get the Full Assembly Name of the Claim provider we want to register</summary>
public override string ClaimProviderAssembly {
    get {
        return typeof(CustomClaimsProvider).Assembly.FullName;
    }
}

/// <summary>Get the Class Type of the Claim provider we want to register</summary>
public override string ClaimProviderType {
    get {
        return typeof(CustomClaimsProvider).FullName;
    }
}

That’s it, you can now register your Claims Provider, and if you want you can use this as is.
Next post will be on these subjects:

  • Create a Trust between your Tusted Identity Provider (STS) and SharePoint 2010
  • Create or Configure your SP2010 WebApplication to use the Tusted Identity Provider

One thought on “Writing your own Trusted Identity provider for SP2010 (2)

  1. Pingback: Writing your own Trusted Identity provider for SP2010 (1) « SharePoint Stef (@vanHooijdonk)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.