Tuesday, December 13, 2016

Sitecore SSO Part 1

This blog post is about SSO across 2 different instances of Sitecore while sharing the same top domain i.e. cookies can be shared across the 2 instances and both instances can access the same DB

I was recently tasked with implementing SSO across two different sitecore sites that are sharing the same top domain. Every instance has different version (8.1 and 6.5) and every instance has its own (core/master/web) databases.
To implement SSO you will have to:
  1. Share authentication/authorization/profiles info
  2. Share authentication cookie across sites
I am splitting them to 2 posts for the sake of clarity

Sharing Authentication/Authorization/Profile info:

Sharing Databases:

Sitecore uses the normal ASP.Net tables schema and builds upon the membership/roles/profiles provider. These providers use core database by default as specified in the Web.Config. To be able to share this existing info, we will need to make changes to the configuration of the new site. So first we need to add a connection in App_Config\ConnectionStrings.config file in the new instance to point to the existing core database of the old site. Let's call this connection oldcore
<add name="oldcore" connectionString="[old site core database connection string]" />
Then we go to the web.config in the new site and point the profile/membership/roles tags to the new oldcore db. Changes are highlighted in yellow (I removed irrelevant configuration for clarity)

<membership defaultProvider="sitecore" hashAlgorithmType="SHA1">
      <providers>
        <clear />
      .....
        <add name="sql" type="System.Web.Security.SqlMembershipProvider" connectionStringName="oldcore".... />
     .........
      </providers>
    </membership>
    <roleManager defaultProvider="sitecore" enabled="true">
      <providers>
        <clear />
        ........
        <add name="sql" type="System.Web.Security.SqlRoleProvider" connectionStringName="oldcore" applicationName="sitecore" />
        .......
      </providers>
    </roleManager>
   <profile defaultProvider="sql" enabled="true" inherits="Sitecore.Security.UserProfile, Sitecore.Kernel">
      <providers>
        <clear />
        <add name="sql" type="System.Web.Profile.SqlProfileProvider" connectionStringName="oldcore" applicationName="sitecore" />
        .....
      </providers>
      .........
    </profile>

This way we only shared the needed info not the whole core database which wouldn't have worked due to version differences

Sharing Domains and User Profiles:

Domains and User profiles in the add user dialog (sitecore 6.5). Client specific info obscured

Domains info are saved in the file App_config\security\domains.config. So this will need to be copied over to the new instance. 
Custom user profiles templates are in the core db in the folder: /sitecore/templates/System/Security
The user profile items themselves are in the core db in the folder /sitecore/system/Settings/Security/Profiles
The easiest way to copy the templates and the items over to the new instance is to create a sitecore package and install them in the new instance.

Profiles Versions incompatibility: 

Due different versions Profiles modified in Sitecore 8.1 cannot be loaded in Sitecore 6.5. While profiles created in Sitecore 6.5 are loaded in Sitecore 8.1
The solution for this was hacky. I had to decompile the new Sitecore.Security.UserProfile from Sitecore 8.1 Sitecore.Kernel.dll and then create in a project in the old sitecore version and then inherit from UserPorfile class in the Sitecore 6.5 Sitecore.Kernel.dll. Then fix all compilation error and remove all the properties the already exist in the old class

namespace UserProfile
{
public class UserProfile : Sitecore.Security.UserProfile
{
         .......
        }
}

and then you will need to modify the web.config in the old Sitecore to be 

<profile defaultProvider="sql" enabled="true" inherits="UserProfile.UserProfile, UserProfile">
I removed some redundant code but didn't go and spend much time to remove as much as possible of redundant code (You can find it here). You can optimize this part. But currently this code allowed Sitecore 6.5 to load profiles modified in Sitecore 8.1
Also there is another problem of caching in each instance where the user profile will load from cache so you will need to reload the profile every time you deal with it.

Conclusion:

Now both sitecore instances share the same login and now we all we need is to share the authentication cookie.

No comments:

Post a Comment