Writing your own Trusted Identity provider for SP2010 (1)

With the introduction of the Windows Identity Framework and SharePoint 2010 it is now possible to have multiple authentication providers on a Single URL on a SPWebApplication.
Especialy in an Extranet scenario this is very usefull:

  • Employees login with their AD Account
  • Partners, suppliers, customers login through a (Custom) Trusted Identity Provider ( Like facebook,OpenID or custom )

Image you have a CRM Application (like Microsoft Dynamics CRM 4) where you store all the relations (contacts) your company has with customers, partners and suppliers. You can use this information, e.g. the email addresses and a custom field for a password, to create your own Identity Provider and provide access to your extranet/collaboration portal based on the information stored in the CRM application.

In 2007 you would extend your SPWebApplication and configure Forms Based Authentication. You would lose the Client Integration Features of Office (2007), and you needed to configure your Membership Provider in the Web.Config.

In 2010 we can use a Identity provider/Claim Provider. There are some major differences / benefits in comparison to a custom Membership Provider. With an Identity Provider ( custom or not ):

  • You can use the Integration Features of the Office (2010) Client
  • All users connect on the same url / WebApplication
  • You can re-use a Identity Provider on more than one WebApp (it's now just a Trust thing)
  • You have Single Sing On (SSO) for free with other WebApps that Trust the same Identity Provider
  • Configuration is done through PowerShell on all servers at once!

This will be a Multi Blog post on "writing your own Trusted Identity provider / Claim Provider for SP2010".
In order to have a working Trusted Identity provider for SharePoint you will need to do a couple of things:

This post will focus on how to create a Custom Security Token Service with the Windows Identity Framework SDK.

  1. Download and install Windows Identity Framework SDK for .Net 4.0 ( and thus VS 2010 )
    SP2010 runs on .Net 3.5 but since this is a Separate IIS WebApplication you use the 4.0

  2. Create a new Web Project with VS2010 based on the ASP.Net Security Token Service Web Site template

    vs2010-wif-4_0-sts-300x101

    This will be the Website used by users to actually login to

  3. Note the following important classes/methods in the project: 
    vs2010-wif-4_0-sts-website

    • CustomSecurityTokenService.cs, and especially the method: GetOutputClaimsIdentity
    • Login.aspx, and especially the CodeBehind: Page_Load
    • Web.Config, and especially the appSettings: IssuerName and SigningCertificateName
  4. Implement the method GetOutputClaimsIdentity,
    here I have chosen to login with the user's email address.

        1: /// <summary>This method returns the claims to be issued in the token.</summary>
        2: /// <param name="principal">The caller's principal.</param>
        3: /// <param name="request">The incoming RST, can be
        4: /// used to obtain addtional information.</param>
        5: /// <param name="scope">The scope information 
        6: /// corresponding to this request.</param>
        7: /// <exception cref="ArgumentNullException">If 'principal' 
        8: /// parameter is null.</exception>
        9: /// <returns>The outgoing claimsIdentity to be included 
       10: /// in the issued token.</returns>
       11: protected override IClaimsIdentity GetOutputClaimsIdentity(IClaimsPrincipal principal, 
       12:                                         RequestSecurityToken request, 
       13:                                         Scope scope) {
       14:     if (null == principal) {
       15:         throw new ArgumentNullException("principal");
       16:     }
       17:     // name = the email address of the user
       18:     string name = principal.Identity.Name;
       19:     // create the new identity
       20:     ClaimsIdentity outputIdentity = new ClaimsIdentity();
       21:     // add new claim based on login/email
       22:     outputIdentity.Claims.Add(new Claim(
       23:       System.IdentityModel.Claims.ClaimTypes.Email, 
       24:       principal.Identity.Name));
       25:     // return the claim
       26:     return outputIdentity;
       27: }
    

    If you want to add more claims you can! You could add claims to the output here to facilitate groups of users.

  5. Implement the Login button/event in the Login page

        1: /// <summary>Handle the Page Load</summary>
        2: /// <param name="sender"></param>
        3: /// <param name="e"></param>
        4: protected void Page_Load(object sender, EventArgs e) {
        5:     // Note: Add code to validate user name, password. This code is for illustrative purpose only.
        6:     // Do not use it in production environment.
        7:     if (!string.IsNullOrEmpty(txtUserName.Text)) {
        8:         // Check credentials agains backoffice (Dynamics CRM 4 in this case)
        9:         if (CrmSQLClient.ValidateContactLogin(txtUserName.Text, txtPassword.Text)){
       10:             // Login info is valid, redirect the user.
       11:             if (Request.QueryString["ReturnUrl"] != null) {
       12:                 FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, false);
       13:             }
       14:             else {
       15:                 FormsAuthentication.SetAuthCookie(txtUserName.Text, false);
       16:                 Response.Redirect("default.aspx");
       17:             }
       18:         }
       19:     }
       20: }
    
  6. Change the login page front end

  7. Add extra functions like "Forgot my password" or "Register for an account" now or later

  8. Deploy your webapplication to IIS.

    You should now be able to login to your custom STS with a browser: 
    vs2010-wif-4_0-sts-website-login-300x108

  9. Create a proper "FederationMetadata.xml" .

    This was a bit hard for me at first. But there is an App for that!

    • Provide the proper values for the WS-Federation Metadata Generator
    • You will need a Certificate to sign the "FederationMetadata.xml" document
    • Copy the new "FederationMetadata.xml" to your published STS Website
  10. Test your new STS WebApplication by logging in. You might get an error when you first test this. Use this url to test if your login page works:https://test-server/default.aspx?&wa=wsignin1.0

  11. There is one thing left to do when you want to use your Identity Provider: install a certificate on the Web Server, and use that to sign the FederationMetadata.xml and update the Web.Config of your provider to reference this certificate in the IssuerName.

Next post will descibe the SPClaimProvider to create and register.

And be sure to check-out some small "issues" with Claims Based authentication