Thursday, April 1, 2010

Authentication Using the TC Integration Module 1.1

Happy April Fools Day. All things are subject to extra suspicion today, but I assure you this blog post is legit. Now then...

In my last post I walked through the installation process for the Telligent Community integration module for Sitecore. In this post I will cover the topic of how authentication works in a little more detail.

The majority of this post is just explanatory information. The instructions on how to get the integration to work (meaning how to get the 2 cookies created) are at the end. I put a "+" in front of those items in case you just want to get the integration to work and will worry about understanding it later :-)

Separate user accounts
Sitecore and TC maintain their own, separate user accounts. These accounts can stay in sync because they share the same user name. After the integration is configured, Sitecore should be used to manage accounts. This includes creating new accounts, setting passwords and assigning roles.

If you are using the integration module with an existing TC instance, the TC users need to be "migrated" to Sitecore. It's not a true migration because the user accounts will still exist in TC. What it does is creates corresponding accounts in Sitecore, so TC users can be authenticated by Sitecore.

Migrating existing TC users
Before you migrate existing TC users, be aware of a couple of things:
  • New accounts will be created in Sitecore.
  • All existing TC users will be migrated. The migration script does not currently support any kind of filtering to control which users are migrated.
  • Existing TC content is not modified in any way.
  • Existing TC users will be renamed in TC. The new user name will be the fully-qualified Sitecore user name. This is the combination of a domain with the user name, such as extranet\rickfielder.
  • Do not run the migration script more than one time.
  • Do not run the migration script if the integration is already in use (meaning Sitecore users have already logged into TC).

TC user migration script

To migrate existing TC users:
  1. Log into Sitecore as an administrator.
  2. Navigate to http://your-server/sitecore modules/Shell/CSSCIntegration/Security/csinstall.aspx.
  3. Select the Sitecore domain the TC users should be created in.
  4. Click the "move users" link.
TC user migration script output

The migration script generates 2 XML files. These files are written to "[sitecore web root]\sitecore modules\Shell\CSSCIntegration\Security":
  • MovedUsers.xml describes the new accounts created in Sitecore. This file contains the username and password for each migrated user. Be aware that passwords are XML-encoded and may not necessarily work if copied directly from this file.
  • FailedUsers.xml describes the TC users who could not be created in Sitecore.
Post-migration considerations
Unfortunately, the migration script doesn't provide any way for an administrator to specify any properties on the Sitecore users that get created. Aside from the Sitecore domain the users are added to. So if you want TC users to be assigned a certain Sitecore role, this is something that you must do manually after the migration.

Another thing to to consider after migrating users is that login, logout, password maintenance and new account creation are all handled by Sitecore. Since TC provides users the ability to do these things, you should hide those link in TC user interface.

Authentication in Sitecore
When using this integration, all authentication is handled by Sitecore. When a user navigates to TC, TC looks for some cookies that Sitecore has created in order to know

When a user logs into Sitecore, 2 cookies are created. These cookies identify that a user has been authenticated and extra information from Sitecore about the user. Since Sitecore and TC must be a part of the same domain, both cookies will be available to TC when the browser navigates to TC. So the user is not automatically logged into TC. Rather, the cookies are set so that when the user navigates to TC, TC can automatically log him in at that point.

The process by which these cookies are created is the same whether the user logs into a published Sitecore website or the Sitecore client - provided Sitecore is configured to create these cookies.

This is not done automatically. The design allows you to control if and when this happens. For example, you may want content authors to have access to TC but not website users. Later in this post I'm going to walk through the configuration needed in order to instruct Sitecore to create these cookies for both published Sitecore websites and the Sitecore client.

But what are these cookies and where do they come from?

Writing the authentication cookie
The first cookie is the authentication cookie. Sitecore creates a System.Web.Security.FormsAuthenticationTicket instance. This object identifies the user who has authenticated. It also contains some data that needs to be transmitted to TC. Specifically, it contains the TC roles that the TC user is assigned.

The name of the authentication cookie is specified in Sitecore's web.config file, in the "authentication" section. My Sitecore instance is configured to use the name ".CommunityServer".

If you're interested in seeing the code that creates the authentication cookie, look at the following:

assembly: Sitecore.CommunityServerSecurityIntegration.SitecoreSide.dll
namespace: Sitecore.CommunityServerSecurityIntegration.SitecoreSide
class: SecurityUtil
method: CreateCookies

Writing the user profile cookie
The second cookie is the user profile cookie. This cookie contains user profile values that are read from Sitecore and made available to TC, which sets those values on the corresponding TC user (or uses those values to create a new TC if one doesn't already exist).

The following is an example of the (unencrypted) user profile cookie value:

Email=Johnson@localhost.com&PublicEmail=Johnson@localhost.com&CommonName=John Johnson

The values that are set in this cookie are determined by the "mappedProfileProperties" section from the Sitecore configuration file "CommunityServerIntegration.config". The only exception is the "Email" value, which is transmitted automatically.

Reading the authentication cookie
When a user clicks a link that takes him to TC, the 2 cookies are available to TC. Just like Sitecore, TC is configured use an authentication cookie named ".CommunityServer".

The TC security extension that was configuring during installation specifies that TC should use the following class to handle forms authentication:

assembly: Sitecore.CommunityServerSecurityIntegration.CommunityServerSide.dll
namespace: Sitecore.CommunityServerSecurityIntegration.CommunityServerSide
class: SitecoreFormsAuthentication

The "ProcessRequest" method is responsible for reading the authentication cookie. After the method confirms that the cookie is valid, it reads the roles that were passed from Sitecore. This ensures the proper roles are assigned to the TC user.

TC handles adding and removing roles from users who already exist in TC, but what about users who don't? Remember, all user management is handled in Sitecore, so it's possible - and even likely - that a user will exist in Sitecore but not in TC. TC will automatically create a new user in this case and will set the roles on the user. The "PostCreateUser" method does this.

Reading the user profile cookie
The "ProcessRequest" method also reads the user profile cookie. It just checks to make sure a value has been set. The underlying TC security extension infrastructure takes the information in that cookie and uses it to create a TC user if necessary and to populate the TC user.

How does Sitecore know when - and if - to write the cookies?
You may not want every Sitecore user to have an account created in TC. Therefore, it is important that you retain some control over when the cookies are written. If no cookies are written, then no single sign-on to TC will occur. The cookies are only written if you want them to be. The next sections explain how to configure this.

+Configuring a Sitecore website to support single sign-on
Website can handle authentication in a variety of ways. This integration supports all of those. However your site's login logic works, add a call to the following method after it runs. This will cause Sitecore to create the 2 cookies that are required for single sign-on to TC:

assembly: Sitecore.CommunityServerSecurityIntegration.SitecoreSide.dll
namespace: Sitecore.CommunityServerSecurityIntegration.SitecoreSide
class: SecurityUtil
method: AfterLogin

You also need to ensure the cookies are deleted when the user logs out. Add the following method call before your code ends the user's session:

assembly:
Sitecore.CommunityServerSecurityIntegration.SitecoreSide.dll
namespace: Sitecore.CommunityServerSecurityIntegration.SitecoreSide
class: SecurityUtil
method: Logout

+Configuring the Sitecore client to support single sign-on
Just like when supporting single sign-on from a published Sitecore website, when configuring single sign-on from the Sitecore client you need to instruct Sitecore to create (and delete) the 2 required cookies.

Hooking into Sitecore's authentication functionality is done by modifying the "loggedIn" and "logout" pipelines. These pipelines are defined in Sitecore's web.config file.

Add the following processor as the first step in the "loggedIn" pipeline:

<processor mode="on" type="Security.CreateCSCookieProcessor, Sitecore.CommunityServerSecurityIntegration.SitecoreSide" />

Add the following processor as the last step in the "logout" pipeline:

<processor mode="on" type="Security.RemoveCSCookieProcessor, Sitecore.CommunityServerSecurityIntegration.SitecoreSide" />


Next steps
After the integration module is installed and configured, it's pretty much smooth sailing. Accessing TC content can be handled in a number of way. I described the options in my introduction to the integration post.

Want to learn more?

4 comments:

  1. Since the migration process creates new passwords for the accounts moved from TC to Sitecore, one would need to write code to allow them to reset or retrieve their password. Correct? There isn't a way to use the built in TC stuff.

    ReplyDelete
  2. When running the migrate script I get the following error. Any thoughts?

    The error occurred while moving the users from Telligent Community to Sitecore.
    '100' is an unexpected token. The expected token is '"' or '''. Line 20, position 74.

    ReplyDelete
  3. Hi Monty, did you fix the problem? I have this problem too. Please help!

    ReplyDelete
  4. I did not get a solution to the problem. It looked like an XML error when it was trying to start up the log files. My client only had a few current users so the time to debug and fix vs. hand migration was an easy choice for them. Wish I knew or had a fix for it though.

    ReplyDelete

Note: Only a member of this blog may post a comment.