Tuesday, December 13, 2016

Sitecore SSO Part 2

This is the second article of the SSO blog posts. You can find the first one here

Sharing Authentication cookie across 2 Sitecore instances:

As I mentioned in my first post, we now want to share the authentication cookie across 2 different sitecore instances (6.5 and 8.1)
Sitecore 8.1 and 6.5 behave differently when dealing with authentication. 
Both use 2 cookies for authentication 
  • .ASPXAUTH (name specified in web.config) 
  • sitecore_userticket
Every version deals with authentication cookie in a different way
  • Sitecore 6.5: When user logs in, both cookies are created. It only uses the .ASPXAUTH cookie for authentication. If you delete or modify the content of sitecore_userticket cookie using a browser plugin, it will not be regenerated. Sitecore is not affected if you modify the content of sitecore_userticket  cookie
  • Sitecore 8.1: When user logs in, both cookies are created. It only uses sitecore_userticket cookie for authentication. If it is missing or modified, then you are considered logged out even if you have the other cookie. sitecore_userticket content is different than Sitecore 6.5 cookie. So sharing it won't make logged in users in Sitecore 6.5 logged in Sitecore 8.1.  .ASPXAUTH cookie can be deleted safely and it will be recreated with every request. You will get an ASP.Net Exception though, if you modify the content of the .ASPXAUTH cookie.
To summarize
  • sitecore_userticket: Different across versions. Important only for Sitecore 8.1 
  • .ASPXAUTH: Same across versions. Important only for Sitecore 6.5
The solution I implmented to solve this was:
  1. Share .ASPXAUTH cookie across instances as both have the same top domain
  2. Recreate the sitecore_userticket in Sitecore 8.1 if .ASPXAuth cookie exists.

Sharing .ASPXAUTH cookie:

You will have to share the same machine key specified in the web.config in BOTH sites:
<machineKey validationKey="xxxxxxxxxxxxxxx"  decryptionKey="xxxxxxxxxx" validation="SHA1" decryption="AES" />
Make the Authentication cookie domain the top domain used by BOTH instances 

<authentication mode="None">
<forms name=".ASPXAUTH" cookieless="UseCookies" domain="[Your top domain here]"/>
</authentication>

Recreating sitecore_userticket  Cookie:

I modified a solution is specified here. The solution specified in the link is good to share the ticket between 2 instances of the same version. In this case sharing the cookie is enough between the domains. But as the content of the cookie is not the same across the old and new versions of sitecore, we have to regenerate it again by adding the code below in the Global.asax file in the NEW sitecore instance. (This was a question I asked on stack exchange here)

protected void Application_EndRequest(object sender, EventArgs e)
{
    var authCookie = HttpContext.Current.Response.Cookies["sitecore_userticket"];

    if (!Request.IsAuthenticated || authCookie == null)
    {
        // when checking response cookies, cookie is created if not exists, so delete now
        HttpContext.Current.Response.Cookies.Remove("sitecore_userticket");
        return;
    }

    //we don't need to make it cross domain as it will be different for every instance 
    //due to version differences.
    //create the ticket cookie. Every Sitecore instance will generate it the way it expects.
    authCookie.Value = TicketManager.CreateTicket(HttpContext.Current.User.Identity.Name, string.Empty);
}

Conclusion:

Now you will have the sign on shared across the 2 versions. This solution may still have some minor issues but all the major challenges are fixed.

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.

Wednesday, October 12, 2016

Sitecore SXA first impressions

First Impressions

When I started working with Sitecore CMS, one of the most confusing parts was the lack pre-built components for simple stuff like adding page content, Facebook comments. This was due to my background in DotNetNuke what comes with lots of first party modules to be used out of the box, I assumed this would be the case with Sitecore. It is the case now with the introduction of Sitecore experience accelerator (SXA).

What is Sitecore Experience Accelerator (SXA)?

SXA is a set of re-usable templates and components that allows you to get your website quickly up and running. In order to achieve this goal SXA has these types out of the box:
Part of SXA components
  • Components: varies from content to composite to media components, etc. They all can be dragged and dropped on place holders. Some components can also host other placeholders (They automatically solve the problem of dynamic placeholders that exist in current Sitecore layouts. In existing projects we have a custom solution for this)
  • Partial Designs: Designs that are to be shared across different types of pages like copyright footer or a top menu or search box
  • Page Designs: Designs that will be used across certain page templates. These designs have either page components or partial designs. There is a mapping between which template should use which page design in the ribbon of the experience editor. Of course you can add components directly on the page but page designs allows you to maintain consistency among all pages with the same template
  • Rendering Variants: Allows the admin to create rendering variants of components that include both html and CSS changes.These variants can be selected in the experience editor in the properties of the component.
  • Creative Exchange Export/Import: Allows the admin to export the whole design to send it to web designers to modify the look and feel of HTML+CSS and the re-imported again to the website.
From what I saw, SXA looks very promising with simple sites can be totally be done with little to no custom development. But from my experience, you will never know till you use SXA in a real life project.

Important links:

SXA at the time of writing is version 1.1 and requires either Sitecore 8.1 or 8.2. 

License Considerations:

SXA requires extra license key "Sitecore.SXA". This key is not in Sitecore license files generated before August,25th 2016. To be able to use SXA, you will need to get a sitecore license file that is generated after this date. Also this means extra money to be paid by the companies purchasing Sitecore.

Final Thoughts and Questions:

  1. This is a really promising technology. It can reduce site development time and comes with lots of useful components out of the box.
  2. This is a new technology that involves some risk and learning curve to master.
  3. I was not able to make the export/import work as expected. I think I missed one of the steps.
  4. Custom development will be needed to meet your requirements that are not fulfilled by the existing SXA components but it is not mentioned in the webinar other than that we should inherit controllers from certain class. And it is not that clear from the documentation.
  5. I don't think we can limit the content of the toolbar depending on the template but I am not sure. This feature will be useful as we may need to limit content authors from adding certain components in certain templates