CRM Customer Portal – User Authentication with Live ID
February 3, 2009 |
Comments (0) 
| Rate this article: 

Background

One of the most important architectural decisions you have to make when you build a customer-facing web portal is the authentication mechanism that you use.  It is difficult to change an authentication mechanism after it is deployed without significant impact on your user community, and as such, it is important to get it right before you bring users into your community.  Before you drop in a standard ASP.NET membership provider such as the SQLMembershipProvider, you might want to consider all of your authentication requirements.  Do you want to be responsible for managing user accounts, resetting user passwords, password complexity rules, password expiration policies?  Do you really want to have to build a full authentication model where you have to provide for lost password retrieval or resetting, additional security questions, and auditing?  Do you want to deal with denial of service attacks and hacking attempts? Do you want to implement one-way password hashing and salting? Does your customer community want to maintain yet another set of credentials?  Do you want to future-proof your authentication mechanism by providing support for federated authentication, Open ID, and CardSpace?  These are all things that you should consider when selecting an authentication mechanism for your site.

Microsoft already has an excellent authentication mechanism that you should carefully consider for all customer-facing websites called Live ID.  Live ID is a federated logon that is in the Microsoft cloud.  Live ID can be federated with customer's Active Directory or other authentication stores, and it also can support Open ID.  Note that some of these features are currently in beta only, but rest assured that if you build with Live ID now, you will be able to reap the benefits of the new capabilities once they are introduced into the production environment.  There are significant benefits of using Live ID for your web authentication.  The most obvious and appreciated benefit is that you will no longer have to be in the business of managing user credentials and resetting passwords.  Live ID takes care of all the password management for you without you having to build and maintain custom code in your website.  Another significant benefit is that there are hundreds of millions of users that already have a Live ID account, and allowing them to use their existing account instead of having to manage yet another set of credentials will be greatly appreciated by your users.

This article will discuss how you can build a customer-facing website, using the CRM as a base for user profiles and Live ID for authentication.

Live ID Basics

The first thing you should know about Live ID is that it is an authentication service.  Your website is not responsible for the actual authentication of the client.  Users will authenticate using web pages served up by the Live ID infrastructure and not using forms on your own website.  It is a complex process and it runs a little sideways compared to the standard ASP.NET membership and forms authentication models, but it is possible to integrate Live ID into your website using forms authentication, a membership provider, and a service handler.  Before I go into the technical details, I want to outline some of the basics of Live ID.  Before you can use Live ID you need to register your application in the Live ID portal.  This involves providing a domain name, a service url, and a secret key.  Live ID has a lot of restrictions on what you can use in the domain name, so plan your domain names carefully and apply for your Live ID early in case you need to get manual approval on your domain name - you don't want to leave that for the last minute.  Registering your application in Live ID is required for your website and Live ID to pass information securely and to allow Live ID to authenticate your users.  The Live ID infrastructure is very secure and all authentication tokens are passed to your website using encryption (based on the secret key that you set in your application registration process).  I should also mention one thing about Live ID - it passes no user information on to your website.  It doesn't even pass the Live ID username on.  The only piece of information that the website gets is a personal user identifier for the site (called a PUID).  This PUID is unique to your site and is not shared with any other sites that the user may log into using their Live ID account.

User Experience using Live ID

The user experience that a customer sees on your website is that they start out anonymously, and see a logon link on one of your pages.  They click on this link, which takes them to a Live ID authentication page, where they enter their credentials.  When they successfully authenticate, they end up back on your site, and if you designed your site properly, they will be fully authenticated to your website, until they click the logout button.  Now consider that the only piece of information that Live ID shares with your website is the PUID - not even the username nor their email address.  That means that the only way you have to uniquely identify the user is a rather long number, but you won't be able to ‘recognize' the user because this PUID is generated by Live ID and is not even known to the user.  This means that the first time that a customer comes to your website, you are going to need to have some form of registration system.  The ASP.NET membership provider model requires that you have a username and an email as a minimum, so your registration system is going to have to ask for an email address as a minimum, and probably a display name as well.  You can use the PUID as a ‘primary key' to locate a user profile for the user.

The technical details of authentication are a little different.  The standard ‘Web Auth' scenarios that Microsoft supports has you placing an IFRAME element on your web page that points to a Live ID page that renders a Sign In or Sign Out text link in that little IFRAME.  I don't find this acceptable for many scenarios, including when you want to use different text or an image for your logon buttons, or when you want to use the actual asp.net mechanisms to detect if a user is logged in or not.  I prefer to render buttons or images with a link to the Live ID pages for logging in or not - this is a bit of a stretch of the official standards, but it works quite well and is well within the security design goals of Live ID.  When a user clicks on a logon link (whether on your website or in the IFRAME), the browser will make a request to the Live ID infrastructure.  The cookies that are set by the Live ID domain will be sent to the logon page, but your site cookies will not.  As such, the link must include a couple of querystring parameters, including an AppID and an application context.  This application context is important as it is passed back to your site when the user completes their authentication so that your authentication handler can have some context to the request and redirect the user to an appropriate place in the application.  The user authenticates with Live ID, and the last page in the Live ID authentication channel will send an HTML page to the browser that will self-POST to your authentication handler.  The POST details will include the action (ie: logon, clearcookies, logout), the encrypted authentication token, and the application context that your website passed along on the logon link.  It is typical practice to build a Live ID authentication handler, and have the authentication handler process the logon, and then forward the user (via a redirect) to an application page (if the user is already registered on the site) or to a registration page (if this is a new user for the site).  The logoff experience is similar except that your authentication handler will have to handle a request to clear cookies (presumably your authentication mechanism is based on cookies) and a final logout request, where you can redirect the user to a safe logout landing page.

ASP.NET Membership and Forms Authentication Model

ASP.NET has a couple of complimentary mechanisms for handling user authentication.  Because these are baked into the .Net framework, these are considered common standards that should be used for all authentication mechanisms.  This ensures that any other module on the website that also has to deal with authentication status will be able to work without any modifications.  The ASP.NET membership system is a provider model that allows you to plug in a provider in the web.config.  The provider has a method called ValidateUser() that is used for authentication.  You can implement Live ID with a membership provider, but it is going to feel a little odd because the actual provider will not be performing any authentication (because that is the responsibility of Live ID and not your provider), and methods like GetPassword() and ResetPassword() are not going to work either.  You will also likely combine the use of a membership provider with ASP.NET forms authentication.  This provides a secure ticket for your website for forms authentication.  Forms authentication also ensures that the HttpContext.Current.Request.User object is properly filled out, which includes a test for User.IsAuthenticated as well as the User.Identity.Name (which in the case of Live ID will likely be the user's PUID or the CRM's ID for the contact record).  These two variables are very important in a web application, and your implementation of Live ID authentication should set these appropriately.  If you also use a membership provider, you can then leverage all the other security goodies that are built into the ASP.NET security model.

The CRM Dimension

Any time you have customers logging into your website, I recommend using a contact record in the CRM to "anchor" the user.  This typically involves adding a ‘username' field to the contact record (or you can use an unused field like ‘nickname') to store the PUID of the user so that you can locate the customer record in the CRM whenever you need to, based on their web identity.  A new user that comes in from a Live Id authentication that doesn't have a contact record with the PUID already set should be considered an unregistered user and should be taken to your registration page.  I recommend doing this by adding the context variables to the HttpContext.Current.Items collection and using a Server.Transfer() call in your authentication handler to the registration form, where the values can be pulled from the context and used in the signup form.  At this time, for an unregistered user, it is important that the authentication handler NOT perform a forms authentication as the user is not really registered yet and should not be considered ‘logged in' by your web application.  The registration form on your site should collect all the necessary information from the user, perform the validation that you require, and then call the Membership.CreateUser() method to create the contact record (your membership provider is tied to the CRM right?) and finally call the FormsAuthentication.SetAuthCookie() method to complete the registration process.  When the page completes this, it can then use the application context that was passed to it from the authentication handler and then choose where to redirect the now fully-authenticated user to.  For subsequent logons, the authentication handler should find the contact record with the PUID as the username, then set the forms auth cookies and redirect to the appropriate location as specified in the context passed back from Live ID.  The important part to remember is that you want to set the user context to the ID of your contact record (or the PUID) and properly maintain the forms authentication status.  This will ensure that all the existing security mechanisms in your site will continue to operate properly.

This mechanism allows for your customers to be anchored in your CRM with a contact record so that you can build self-serve web applications that are related to their contact record in your CRM.  This allows you to build an interesting and powerful set of web applications that your customers will find value in using.  It should also be noted that this website authentication mechanism is not the same as the authentication mechanisms for users in the CRM.  Your customers are really contact records in the CRM and do not have CRM accounts - that means that they don't consume user licenses, and it also means that they cannot access CRM user interfaces.  If you are building a partner site that you desire to have them use the CRM user interfaces, you should not use Live ID on the web portal for them to use - you should use an Active Directory authentication provider (assuming on-prem or partner hosted models).  Just remember - your internal users are users in the CRM, and your customers are contacts.

Other Considerations

One of the design consequences in using Live ID is that a customer will have a unique PUID (that is what the U is for) for every Live ID application.  Each Live ID application will have a unique domain name.  If you desire to offer many websites to a common user community that you want to tie into a single CRM, you are going to want to micro-federate your Live ID so that you can have a common PUID across all of your web properties.  The Live ID team has promised improvements to make this easier in the future, but it is possible for you to do this by using a common authentication website that interacts with Live ID, but also works with authentication handlers on your own site.  This topic is too large to be covered in this article, but if you are looking to have multiple web properties, you might want to consider this up front before you implement your first Live ID website.

The mechanisms described in this article are suitable for a website where users sign-up on your website.  You may already have contact records for users, or you may not want to offer the option of ‘signing up' and instead have an invitational model.  It is possible to support an invitation model using the CRM with the same authentication handlers, membership providers, and forms authentication.  Again, this is a topic that is too large to be covered in this article.

Another consideration that you might have is that Microsoft is building out quite a large set of web services that are branded under the Live or Mesh name.  Most of these services have SDKs that enable sharing of information from their own data stores to third-party websites.  This information sharing is always done using a consent model, and all of these consent services are using Live ID.  If you would like to keep your application future-proof and allow for easy integration into some of these services, pursuing a Live ID mechanism for authentication is a good first step.

Next Steps

You should begin by studying the Live ID SDK.  You will have to write an authentication handler, and a membership provider that can work with Live ID and your CRM.  You will also have to provide a signup page or implement some form of invitation mechanism on your site.  That is a lot of code, and some of the code is a little tricky.  If you want to take the easy way out, you may consider getting a license of the ADXSTUDIO CRM Developer Toolkit as we have all of the required modules and providers included in the toolkit and lots of great examples of how to quickly and easily get your site up and running using Live ID for authentication and with tight integration with your CRM.  You will also find a lot of other useful things to help you build customer facing applications with tight integration with your CRM.

Links & Attachments