Thursday, February 15, 2018

Getting SXA to work with Solr in Sitecore 9

When I started working with Sitecore 9 (initial release) and SXA 1.5.

I followed the instructions for installing Sitecore 9 and then Sitecore Powershell extension 4.7 and SXA 1.5.
I started exploring and everything seemed to work fine until I started working with page list and search components. These components need item query / search scope to be able to retrieve items based on certain query.
I was able to build the item query and go the results in the CM environment but when I publish the pages and load these pages, queries never returned anything.
Tried re-indexing, re-publishing but doesn't seemed to work.
Finally #Slack came to the rescue.

Here are couple of things that worked for me.
Fix 1
In Sitecore 9 initial release you need to enable one of the configuration file under Include\z.Foundation.Overrides depending on your search platform you are using. In my case it was Solr and hence I had to enable Sitecore.XA.Foundation.Search.Solr.config.
But enabling this caused my Solr master and web indexes failed to build and even the schema was not getting populated (Control Panel -> Populate Solr Schema).
Having no clue, someone in the slack #sxa channel mentioned that Sitecore 9 initial release have an issue in the above file. You need to remove the $id from the core and put the actual core name for your solr indexes. In my case it was xp1_master_index and xp1_web_index.
The changed configuration in Sitecore.XA.Foundation.Search.Solr.config is shown below with highlighted section

            Sitecore.XA.Foundation.Search.Providers.Solr.SolrSearchIndex, Sitecore.XA.Foundation.Search.Providers.Solr
                Sitecore.XA.Foundation.VersionSpecific.Search.ItemCrawler, Sitecore.XA.Foundation.VersionSpecific
            Sitecore.XA.Foundation.Search.Providers.Solr.SolrSearchIndex, Sitecore.XA.Foundation.Search.Providers.Solr
                Sitecore.XA.Foundation.VersionSpecific.Search.ItemCrawler, Sitecore.XA.Foundation.VersionSpecific

Fix 2
Una Vanhoeven also suggested to add couple of dynamic fields in Solr for master and web cores. Her blog explains it very well and hence not going to add same steps here.. Link to her blog

Once you are done with above two fixes, rebuild master index, re-publish and re-build web index. Now not only your master and web indexes will get built properly, your SXA components will also start working

Hope this helps

Friday, January 26, 2018

Error in Sitecore SXA theme selection


While working on SXA in Sitecore 9, I was facing an error in Sitecore experience editor where i was trying to select a theme. But it was throwing below error

Server Error in '/' Application.

End of string expected at position 51.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: Sitecore.Data.Query.ParseException: End of string expected at position 51.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

[ParseException: End of string expected at position 51.]
   Sitecore.Data.Query.QueryParser.Raise(String error) +203
   Sitecore.Data.Query.QueryParser.DoParse(String query) +83
   Sitecore.Pipelines.GetLookupSourceItems.ProcessQuerySource.Process(GetLookupSourceItemsArgs args) +163
   (Object , Object[] ) +71
   Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) +469
   Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain) +22
   Sitecore.Web.UI.HtmlControls.Data.LookupSources.GetItems(Item current, String source) +459

[LookupSourceException: Invalid lookup source "query:$compatibleThemes": End of string expected at position 51..]
   Sitecore.Web.UI.HtmlControls.Data.LookupSources.GetItems(Item current, String source) +623
   Sitecore.XA.Foundation.SitecoreExtensions.CustomFields.FieldTypes.LookupNameLookupValue.GetValueHtmlControl(String id, String value) +198
   Sitecore.XA.Foundation.SitecoreExtensions.CustomFields.FieldTypes.LookupNameLookupValue.BuildParameterKeyValue(String key, String value) +519
   Sitecore.XA.Foundation.SitecoreExtensions.CustomFields.FieldTypes.LookupNameLookupValue.BuildControl() +362
   System.Web.UI.Control.LoadRecursive() +68
   System.Web.UI.Control.LoadRecursive() +162
   System.Web.UI.Control.AddedControl(Control control, Int32 index) +11890468
   Sitecore.Web.UI.Sheer.ClientPage.AddControl(Control parent, Control control, String placeholder) +233
   Sitecore.Shell.Applications.ContentEditor.EditorFormatter.AddEditorControl(Control parent, Control editor, Field field, Boolean hasRibbon, Boolean readOnly, String value) +241
   Sitecore.Shell.Applications.ContentEditor.EditorFormatter.RenderField(Control parent, Field field, Item fieldType, Boolean readOnly, String value) +1490
   Sitecore.Shell.Applications.ContentEditor.EditorFormatter.RenderField(Control parent, Field field, Item fieldType, Boolean readOnly) +185
   Sitecore.Shell.Applications.ContentEditor.EditorFormatter.RenderField(Control parent, Field field, Boolean readOnly) +380
   Sitecore.Shell.Applications.ContentEditor.EditorFormatter.RenderSection(Section section, Control parent, Boolean readOnly) +252
   Sitecore.Shell.Applications.ContentEditor.EditorFormatter.RenderSections(Control parent, Sections sections, Boolean readOnly) +173
   (Object , Object[] ) +71
   Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args) +469
   Sitecore.Pipelines.DefaultCorePipelineManager.Run(String pipelineName, PipelineArgs args, String pipelineDomain) +22
   Sitecore.Shell.Applications.ContentManager.Editor.Render(RenderContentEditorArgs args, Control parent) +558
   Sitecore.Shell.Applications.ContentManager.FieldEditorForm.RenderEditor(Border parent) +388
   Sitecore.Shell.Applications.ContentManager.FieldEditorForm.UpdateEditor() +187
   Sitecore.Shell.Applications.ContentManager.FieldEditorForm.OnPreRendered(EventArgs e) +37

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
   System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) +210
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +146
   Sitecore.Reflection.ReflectionUtil.InvokeMethod(MethodInfo method, Object[] parameters, Object obj) +89
   Sitecore.Shell.Applications.ContentManager.FieldEditorPage.OnPreRender(EventArgs e) +164
   System.Web.UI.Control.PreRenderRecursiveInternal() +110
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3624


The issue was, I named my theme as "company-site". Please note "-" hyphen in between the name, which caused the fast query used to fetch theme names fail and was throwing above error. I renamed the them and it all started working

Saturday, December 30, 2017

Conflict between Custom Sitecore Helix solution and Sitecore Experience Accelerator

I ran into issues when I was implementing my custom Helix based Sitecore solution where i had created my own Foundation, Feature and Project folders in Sitecore and later on decided to install Sitecore Experience Accelerator (SXA 1.5) on Sitecore 9

Sitecore Experience Accelerator itself comes bundled with these folders out of the box and if you install SXA after you deployed your custom Helix based solution having your own custom Foundation, Feature and Project folders, it will cause multiple issues.

  • SXA has its own folder definitions and will not recognize your own folders in Sitecore content tree if they pre-exist.
  • SXA will not work as expected as in some cases the Sitecore Powershell modules for SXA is considering the path of the folders than the GUID of these folder items. Now having two folders with same name at the same location causes confusion in SXA functionality and some of the features wont work. I got this error when I tried creating a site.

18404 16:42:41 INFO  Executing PsSitecoreItemProvider5.Start(providerInfo='Sitecore')

12196 16:42:41 INFO  Executing a script in ScriptSession '$scriptSession$|s4vp2xehh0dbnaigl0bqqbfs|d90f9428-5823-49a5-b7ad-2fe01ea6d874'.

12196 16:42:41 INFO  The script execution in ScriptSession '$scriptSession$|s4vp2xehh0dbnaigl0bqqbfs|d90f9428-5823-49a5-b7ad-2fe01ea6d874' completed in 6 ms.

ManagedPoolThread #3 16:42:41 ERROR Cannot bind argument to parameter 'TenantTemplateLocation' because it is null.

ManagedPoolThread #3 16:42:41 INFO  The script execution in ScriptSession '$scriptSession$|s4vp2xehh0dbnaigl0bqqbfs|526e5448-b4cc-44c2-9b9d-bff3f751d8c1' completed in 11848 ms.

  • Though I haven't digged enough to find out where this error was coming from, I see powershell code snippets used in SXA that looks like using layer names in the path to query some of the elements and I suspect if that is the issue.

    process {

        Write-Verbose "Cmdlet Get-GridSetup - Process"

        $query = "/sitecore/system/Settings/$Layer//*[@@templatename='Grid Setup']"

        $definitions = Get-Item -Path master: -Language "en" -Query $query



  • If you are planning to use helix based architecture for your implementation along with SXA, make sure you first install SXA before you start creating your own layer folders.


If you are planning to use SXA then install it before getting on the Helix based implementation.
Change your foundation serialization configuration not to include foundation, feature and project folder items as it would be assumed that you will install SXA content delivery packages yourself and that will have these folders created.

Happy SXA & Helix implementation

Thursday, November 23, 2017

Deploying Sitecore 9 to Azure PaaS with Sitecore Azure Toolkit

While there is bunch of documentation available to get started with Sitecore deployment on Azure PaaS, I am sharing my experience of deploying a simple Sitecore 9 deployment topology (XPSingle).

For you to be able to deploy Sitecore 9 on Azure PaaS you need few pre-requisites. These are well documented by Sitecore and you can refer it in the Sitecore Azure Toolkit documentation.

Since most of the pre-requisites were in place for me here are few things you need to get started

Sitecore Azure Toolkit 2.0 

  • Download the zip, Unblock it, and unzip it in an appropriate place in your file system.
  • You can import the Powershell module from Sitecore.Cloud.Cmdlets.psm1 in tools directory and explore the command-lets

Sitecore 9 Web deployment packages

  • Based on the topology you want to deploy, download the web deploy packages (scwdp files) from Sitecore download portal. In my case it is Sitecore 9 XPSingle and I downloaded two packages (one for sitecore - Sitecore 9.0.0 rev. 171002 (Cloud) and another is for xConnect  - Sitecore 9.0.0 rev. 171002 (Cloud)
  • As we will need these packages accessible over internet, upload these packages in an Azure blob storage account under container named based on your convenience. Please review the type of container and your access requirements. In my case, since I was experimenting, I kept it publicly accessible.

ARM templates

  • Download azuredeploy.parameters.json template from github.
  • I preferred the released version Sitecore Azure Quickstart Templates 2.0 (, but you may want to refer the latest from the repository
  • Sitecore Azure Toolkit commandlets passes parameters to Azure ARM template to provision your infrastructure and hence you need to have only the azuredeploy.parameters.json file on your local machine.
  • As a best practice, I would suggest you to deploy your ARM templates in your own repository OR azure storage which is accessible over internet as this will not have any impact of changes done on git and you are working against a stable template.


Create a pkcs 12 self-signed certificate file as give below (use Powershell command prompt in administrative mode - for some reason powershell ISE did not work for me).

Please note: I did it for on-premise deployment of Sitecore 9 to secure Solr instance but same file would do if you want to avoid creating new one.

-genkeypair -alias solr-ssl -keyalg RSA -keysize 2048 -keypass secret
-storepass secret -validity 9999 -keystore solr-ssl.keystore.jks -ext
SAN=DNS:localhost,IP: -dname "CN=localhost, OU=Organizational
Unit, O=Organization, L=Location, ST=State, C=Country"

keytool -importkeystore -srckeystore solr-ssl.keystore.jks -destkeystore solr-ssl.keystore.p12 -srcstoretype jks -deststoretype pkcs12

Now since this is a self-signed certificate and not from a trusted auhority, you also need to inclued an additional parameter in azuredeploy.parameters.json file as below

    "allowInvalidClientCertificates": {
      "value": true

You can also refer the whole walkthrough and more details of the entire deployment process here -> Walkthrough: Deploying a new Sitecore environment to the Microsoft Azure App service

Deployment Script

Once you have everything in place, create a new Powershell script in Windows Powershell ISE (in administrative mode). Replace values with you own setup (refer comments for each line) and start deploying

##Path to Sitecore Azure Toolkit commandlet script that you will be importing

$SCAzToolkitPath = "C:\Sitecore9\Azure\Sitecore Azure Toolkit 2.0.0 rev.171010\tools\Sitecore.Cloud.Cmdlets.psm1"

##this is the name used for creating a resource group on azure and also will be a prefix for lot of services.
##Keep it small case with letters and numbers only. Follow azure resource naming rules.
$DeploymentId = "sc9xpsingle"

##Certificate .p12 file created using keytool. Replace it with your physical location
$CertFile = "C:\Sitecore9\Azure\Certificate\solr-ssl.keystore.p12"

##Path to your license file
$LicenseXmlPath = "C:\MyWork\Sitecore\License\license.xml"

##Deployment region - Refer Sitecore Azure deployment compatibility matrix here
$Location = "East US"

##Your azure subscription ID, copy it from your azure portal by navigating it to subscription and selecting appropriate subscription under which you want to deploy your instance
$SubscriptionId = "< your subscription ID >"

##This has to be internet addreseable URL otherwise you face errors as shown in gotcha 1.
$ARMTemplate = "https://<storageaccount>"

##This is a physical (local) path
$ARMParametersTemplate = "C:\Sitecore9\Azure\Sitecore-Azure-Quickstart-Templates-2.0\Sitecore-Azure-Quickstart-Templates-2.0\Sitecore 9.0.0\XPSingle\azuredeploy.parameters.json"

##Set the parameters that needs to be passed to the ARM templates
##Please note that I have uploaded the deploy packages on azure storage at a particular location, your location may vary

$Parameters = @{
    "authCertificateBlob" = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes($CertFile));
    "singleMSDeployPackageUrl" = "https://<storageaccount>";
    "xcSingleMsDeployPackageUrl" = "https://<storageaccount>";
    "authCertificatePassword" = "secret";
    "sitecoreAdminPassword" = "Passw0rd";
    "sqlServerLogin" = "badal";
    "sqlServerPassword" = "Passw0rd"; ##ensure you have the password according to SQL Azure password policy ->
    "location" = $Location;
    "deploymentId" = $DeploymentId

##Import your Sitecore Azure Toolkit commandlets
Import-Module -verbose $SCAzToolkitPath

Add-AzureRmAccount ##Add-AzureAccount will not work

Set-AzureRmContext -SubscriptionId $SubscriptionId

##make sure you use -verbose to see the output of deployment status as it happens
Start-SitecoreAzureDeployment -verbose -Location $Location `
                                -LicenseXmlPath $LicenseXmlPath `
                                -SetKeyValue $Parameters `
                                -Name $DeploymentId `
                                -ArmTemplatePath $ARMTemplate `
                                -ArmParametersPath $ARMParametersTemplate

Deployment takes about 20-30 mins. Once your deployment is successful, you can login to sitecore as you would normally on your local deployment. In Azure, It deployes about 19 resources (app service plan, Azure App, Azure Search, SQL Databases, Redis Cache and bunch of others) as shown below

Sitecore Azure Resources for XP Single deployment topology

Few Gotchas / Errors I faced

1. Phyical path Vs URL for your azure template
I had given the physical path of my azuredeploy.json template and azure could not identify the nested templates during deployment. I got this error below and I changed it to the internet addressable path

'The template resource 'templateLinkBase' at

line '28' and column '30' is not valid: The language expression property 'templateLink' doesn't

exist, available properties are 'template, parameters, mode, provisioningState'

2. When I changed the path, I also changed the path of the parameters template to internet addressable path and i got this error. Hence you need to have the parameters file (azuredeploy.parameters.json) on your local machine

Start-SitecoreAzureDeployment : A parameter cannot be found that matches parameter name 'Raw'.
At C:\Sitecore9\Azure\DeploymentScript\xpSingleDeploy.ps1:27 char:1
+ Start-SitecoreAzureDeployment -verbose -Location $Location `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Start-SitecoreA 
3. Ensure you execute your Start-SitecoreAzureDeployment commandlet with -verbose to get enough clues on whats going wrong

4. Also ensure you set the parameters key value pair in @parameter variable for deploymentId, and location as this did not seem to be passed though the command (as you can see I have done it at both places - especially for location). Also check other paramters as shown in the script above

5. I also gave deploymentID as something with capital letters, which was not accepted as a valid resource names for Azure hence keep it small case.

Tuesday, November 14, 2017

Federated Authentication for Sitecore 9 integrating with Azure AD - Step by Step

I started integrating Sitecore 9 with Azure AD and I ended up at two resources (in fact 3, but only 2 public sources, 3rd one was only accessible to people who were registered for Sitecore 9 early access program)

First: Sitecore documentation:

Bas Lijten blog on enabling the federated authentication with Auth0 helped a lot. and he has also added some sample code in the early access program forum.

But I thought most likely, enterprises would like to integrate with Azure AD for following reasons
  1. Relatively widely used Identity / Federated identity provider
  2. Allows you to sync with your enterprise active directory
  3. And allows you to federate with other organizations given the current era of digital landscape where multiple agencies are involved in your brand story e.g. Technology partners, infrastructure partners, creative agencies and many more.

  • Sitecore 9 uses ASP.NET Identity and OWIN middleware. Sitecore.Owin and Sitecore.Owin.Authentication are the libraries implemented on top of Microsoft.Owin middleware and supports OpenIDConnect out of the box, with little bit of code you need to add yourself :)
  • The scenario I am covering here is for CM environment. For CD environments it should be pretty straight forward.

So here are the steps to get it working, with some gotchas to keep in mind while troubleshooting

Create an Azure AD service in your azure subscription as shown below

Optional:  Map your AD to your custom domain and then create a TXT record on your domain service provider with the properties as shown below and then verify that on Azure

Register an application on Azure AD through "App Regitration" as shown below. in this case is my sitecore instance name I created locally. Also note the Home page URL

Also configure the ReplyURL where the token will be posted to the same URL as Home page.

Create a few groups representing your sitecore roles e.g. Developer, Administrator, Content Author etc.. (Please take note of the Obeject ID shown when you create these groups as this will be needed in the configuration later for transforming these into Sitecore roles)

Create few users and add different users to different groups

Edit the application manifest file to change the default groupMembershipClaims property from null to SecurityGroup / All. This is needed to send the group claims as part of the token. I struggled to get users log in into Sitecore despite of being authenticated by AD as it doesnt have any group claim and as a result the transformation to convert them into Sitecore roles will not kick-in and Sitecore will prompt saying you do not have appropriate accesses to login. Screenshot of the manifest is shown below and this can be edited by clicking on the newly registered app ( in my case) and then clicking on Manifest (as shown below)

At this point your Azure AD instance is setup to authenticate users. Next thing we need to do is integrate it with Sitecore and for that we need to add a patch configuration and a custom processor.

Create a visual studio project by creating a new MVC Empty project and remove all un-necessary files and folders, global.asax, app_data, app_start and web.config file (highlighted below)

Add a nuget source for Sitecore using Tools - > Nuget Package Manager -> Package Manager Settings as shown below

Add web.config from your Sitecore instance into the visual studio solution

Create a publish profile (file system) to publish your project output into Sitecore root folder

Exclude files to be deployed as part of the publish in the custom publish profile you created , as indicated below
<?xml version="1.0" encoding="utf-8"?>
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit 
<Project ToolsVersion="4.0" xmlns="">
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
Once your AD instance is setup, and your solution is created, you can start integrating it with Sitecore and the first step would be to enable Sitecore.Owin.Authentication.Enabler.config file which is available in App_Config\Include\Examples.

Please note, all your custom config files must go in Include folder and you should not be changing anything in Sitecore layer (layered configuration). Below is the snapshot of my solution view where configuration files are created

Also add a custom patch configuration file to include your other federated authentication configurations. I will explain each bit of it in inline comments in the configuration below
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="" xmlns:role="">
  <sitecore role:require="Standalone or ContentDelivery or ContentManagement">
      <!-- Below settings describes Azure AD details to which we are integrating with -->
      <setting name="ClientId" value="application ID when you register your application into Azure through APP registration" />
      <setting name="AADInstance" value="{0}" />
      <setting name="Tenant" value="your azure active directory e.g." />
      <setting name="PostLogoutRedirectURI" value="" />
      <setting name="RedirectURI" value="" />
        <!-- This is the custom processor that gets executed when azure AD posts the token to Sitecore -->
        <processor type="SitecoreFedAuthWithAzureAD.Pipelines.CustomAzureADIdentityProvider, SitecoreFedAuthWithAzureAD" resolve="true" />
      <identityProviders hin="list:AddIdentityProvider">
        <identityProvider id="" type="Sitecore.Owin.Authentication.Configuration.DefaultIdentityProvider, Sitecore.Owin.Authentication">
          <param desc="name">$(id)</param>
          <param desc="domainManager" type="Sitecore.Abstractions.BaseDomainManager" resolve="true" />
          <caption>Sign-in with Azure Active Directory</caption>
          <transformations hint="list:AddTransformation">
            <!-- you need to have and Idp Claim for this to work -->
            <transformation name="Idp Claim" ref="federatedAuthentication/sharedTransformations/setIdpClaim" />
            <!-- This is to transform Azure group into Sitecore Role. The claim value below is the object id that needs to be copied from Azure -->
            <transformation name="Transform to Sitecore DEV Role" type="Sitecore.Owin.Authentication.Services.DefaultTransformation, Sitecore.Owin.Authentication">
              <sources hint="raw:AddSource">
                <claim name="groups" value="2656b61c-748a-4d52-904c-099044c4dcd5" />
              <targets hint="raw:AddTarget">
                <claim name="" value="Sitecore\Developer" />
      <!-- Property initializer assigns claim values to sitecore user properties -->
      <propertyInitializer type="Sitecore.Owin.Authentication.Services.PropertyInitializer, Sitecore.Owin.Authentication">
        <maps hint="list">
          <map name="email claim" type="Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper, Sitecore.Owin.Authentication">
            <data hint="raw:AddData">
              <!--claim name-->
              <source name="" />
              <!--property name-->
              <target name="Email" />
          <map name="Name claim" type="Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper, Sitecore.Owin.Authentication">
            <data hint="raw:AddData">
              <!--claim name-->
              <source name="" />
              <!--property name-->
              <target name="Name" />
        <mapEntry name="all" type="Sitecore.Owin.Authentication.Collections.IdentityProvidersPerSitesMapEntry, Sitecore.Owin.Authentication">
          <sites hint="list">
          <!-- Registered identity providers for above providers -->
          <identityProviders hint="list:AddIdentityProvider">
            <identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='']" />
          <!-- ExternalUserBuilder is what creates a user with customusername in Sitecore and assigns roles based on claim transformation configured above -->
          <externalUserBuilder type="Sitecore.Owin.Authentication.Services.DefaultExternalUserBuilder, Sitecore.Owin.Authentication">
            <param desc="isPersistentUser">true</param>
Add below nuget package references for us to use OpenIDConnect as the identity provider

Add code to process your authentication events

using Microsoft.Owin.Security;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Diagnostics;
using Sitecore.Owin.Authentication.Configuration;
using Sitecore.Owin.Authentication.Pipelines.IdentityProviders;
using Sitecore.Owin.Authentication.Services;
using System.Globalization;
using System.Threading.Tasks;

namespace SitecoreFedAuthWithAzureAD.Pipelines
    public class CustomAzureADIdentityProvider : IdentityProvidersProcessor

        public CustomAzureADIdentityProvider(FederatedAuthenticationConfiguration federatedAuthenticationConfiguration) : base(federatedAuthenticationConfiguration)

        protected override string IdentityProviderName => "";

        protected override void ProcessCore([NotNull] IdentityProvidersArgs args)
            Assert.ArgumentNotNull(args, nameof(args));

            var identityProvider = this.GetIdentityProvider();
            var authenticationType = this.GetAuthenticationType();

            string aadInstance = Settings.GetSetting("AADInstance");
            string tenant = Settings.GetSetting("Tenant");
            string clientId = Settings.GetSetting("ClientId");
            string postLogoutRedirectURI = Settings.GetSetting("PostLogoutRedirectURI");
            string redirectURI = Settings.GetSetting("RedirectURI");

            string authority = string.Format(CultureInfo.InvariantCulture, aadInstance, tenant);

            args.App.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
                Caption = identityProvider.Caption,
                AuthenticationType = authenticationType,
                AuthenticationMode = AuthenticationMode.Passive,
                ClientId = clientId,
                Authority = authority,
                PostLogoutRedirectUri = postLogoutRedirectURI,
                RedirectUri = redirectURI,

                Notifications = new OpenIdConnectAuthenticationNotifications
                    SecurityTokenValidated = notification =>
                        var identity = notification.AuthenticationTicket.Identity;

                        foreach (var claimTransformationService in identityProvider.Transformations)
                            claimTransformationService.Transform(identity, new TransformationContext
                                IdentityProvider = identityProvider

                        notification.AuthenticationTicket = new AuthenticationTicket(identity, notification.AuthenticationTicket.Properties);

                        return Task.CompletedTask;


Few Gotchas:
  • Make sure you are not logged in into azure portal as that also uses the azure ad single sign on and the moment you click on federated sign in button in Sitecore, it will take your current session cookie with azure ad and return claims for that user without even asking you to enter credentials. I therefore used incognito window always during debugging.
  • Also note that it does not use the credentials entered in the default sitecore login screen.
  • When you are experimenting with Azure AD always use incognito mode (as mentioned above)
  • Sitecore logout does not kill session with azure ad at this point based on my experiment, but you can extend this pipeline. I have raised  ticket with Sitecore on this.
  • Also ensure that you edit application manifest for your registered application with AD to send groupClaims as indicated in my blog. In the absense of that and the transformation rule for group claim to Sitecore role, you will not be able to login to Sitecore

Friday, October 27, 2017

Connecting Sitecore Rocks to Sitecore 9 with Visual Studio 2017 securely

In Sitecore 9 you will not get access to install Hardrock services required by Sitecore Rocks to connect to Sitecore instance.

If you follow the normal process, you get following message when you try to connect

Sitecore Rocks Connection Error

To setup a connection you need authorize access to sitecore/shell/webservice location in web.config by adding a location attribute and allowing only authenticated users.

  <location path="sitecore/shell/WebService">



        <allow users="*" />




Typically you will find other posts or suggestions to allow access to anonymous (?) and authenticated (*) users but that is not needed.

You should allow access to this location only for authenticated users

I tried to narrow it down further to allow only for a specific user e.g. to sitecore/admin but that simply throws back the same screen shown above and fiddler indicates that it is throwing the login page which means its not able to authenticate in that attempt.

Monday, October 23, 2017

Installing Solr 6.2.1 as a Windows Service for your Sitecore Installation

When I was trying to get Solr installed for my Sitecore 9 installation, I struggled to get it installed as Windows Service, but finally got it working. Here is what how I did it

Enabling SSL for your solr installation

First create self-signed certificate using keytool as shown below (I am executing this in the current path of C:\solr-6.2.1\server\etc

-genkeypair -alias solr-ssl -keyalg RSA -keysize 2048 -keypass <yoursecretpwd>-storepass <yourstorepwd> -validity 9999 -keystore solr-ssl.keystore.jks -ext
SAN=DNS:localhost,IP: -dname "CN=localhost, OU=Organizational
Unit, O=Organization, L=Location, ST=State, C=Country"

keytool -importkeystore -srckeystore solr-ssl.keystore.jks -destkeystore solr-ssl.keystore.p12 -srcstoretype jks -deststoretype

Now install certificate in the trusted authority store as shown below
Double-click the generated .p12 - for example, C:\Solr-6.2.1\server\etc\solr-ssl.keystore.p12 - and go through the wizard, selecting the following:
  • Store Location: Local Machine
  • File name: [NO CHANGE]
  • Password: secret (or the value of -keypass used in your own environment)
  • Certificate store: Trusted Root Certificate Authorities
  • Post that make sure your solr properties in (file is in the bin directory) is configured correctly to enable SSL. In my case this is how it looked like

set SOLR_SSL_KEY_STORE=C:\solr-6.2.1\server/etc/solr-ssl.keystore.jks

set SOLR_SSL_KEY_STORE_PASSWORD=<your ssl key store pwd>

set SOLR_SSL_TRUST_STORE=C:\solr-6.2.1\server/etc/solr-ssl.keystore.jks

set SOLR_SSL_TRUST_STORE_PASSWORD=<your ssl trust store password>



Usually I keep key store and trust store passwords the same

Running Solr as Windows Service

Your typical sc create command times out and does not result in successful start of the service (here is the command I used)

sc create Solr621 binPath="C:\Solr 6.2.1\bin\start.cmd start -f" DisplayName= "Solr 6.2.1" start= "auto"
sc start Solr621

After digging a bit, came across nssm (the non-sucking service manager :)) and downloaded the latest version 

Once you install nssm (I used 2.24 version), open command prompt in administrative mode and execute this command

nssm install Solr621


  • After unzipping nssm I added nssm path into PATH environment variable
  • The name Solr621 above can be any name you want to give your service

A window will open where you can mention the attributes as shown in the snapshot below

NSSM service properties

NSSM service display name and description

In the first screen above, set the path pointing to solr.cmd and startup directory as your solr installation bin directory.
Notice the arguments set to start solr service in foreground (start -f)

In the Details tab, enter the display name and description as you wish, with startup type as Automatic so that the service starts automatically when you restart your machine.

Note that this installation procedure is ideal for local machine installation. For production deployments refer to solr documentation

Happy Searching !!

Tuesday, February 28, 2017

Installing Sitecore Experience Accelerator Reference Implementation from Cognifide

I have been struggling to find enough documentation OR some reference implementation for Sitecore Experience Accelerator (SXA) for some time now. Thanks to Michaell West for pointing me to this repository of SXA reference implementation from Cognifide.

  1. Download the code, configuration and serialized items from github 
  2. Open the visual studio solution in Administrative mode
  3. Add a reference to the Siteocre Unicorn Nuget package. This will add some configuration files as well.
  4. Change the showcaseFolder in Sitecore.XA.Project.Showcase.User.config to point to the location where you have extracted the github repository. You dont know need to touch any of the files. In my case it looks like this


  6. Create a publishing profile to publish the site to file system in your sitecore website root folder. I had pre-installed Sitecore 8.2 already and gave a file system path of "Website"
  7. Once you publish, this adds all the configurations required on Sitecore instance.
  8. Login as administrator and got to http://<yourinstancename>/unicorn.aspx
  9. Click on sync to sync Content, Media and Templates from file system to Sitecore. This takes about 3-4 mins to install and publish all Sitecore items
  10. Once everything is installed, you should see a tenant called showcase and a site called int as shown below

Explore various pages, components and variants from SXA and learn.

Happy Learning !!

Tuesday, December 27, 2016

Working with Sitecore SPEAK dialog

In old world of Sitecore (Sheer UI), you used to work with SheerResponse to open the dialog box as shown below

SheerResponse.ShowModalDialog(new ModalDialogOptions(url)
  Width = "100",
  Height = "200",
  Response = true,
  ForceDialogSize = true

The same logic will work when you are opening a SPEAK page as a dialog from a non-speak interface

Sitecore documentation here is a good start to understand various options. This blog is not about re-iterating those options but something that is not documented (or at least i haven't seen).

I was in a situation where I had 2 SPEAK pages and I wanted to open second page as a modal dialog from the first SPEAK page. Though the last section of above documentation provides you a reference but documentation is incomplete.

When you are trying to open one SPEAK page from another in a modal form (i.e. until you respond to the dialog you cannot do anything on the parent window, either by means of taking some action or closing the window) you have to follow these steps

  1. Add a DialogWindow rendering in your SPEAK page
  2. Add Frame component in DialogWindow placeholder
  3. Set the Frame Source URL property to the second SPEAK page you want to open in the dialog window. I am doing this in code as shown below
            showDialog: function (td) {
                try {
                    //adding couple of querystrings as the dialog shows the content based on these parameters (passed from first page)
                    td = td || 0;
                    var app = this;
                    var jd = Sitecore.Helpers.url.getQueryParameters(window.location.href)['jd']; 
                    var url = "SecondPage?jd=" + jd
                    if (td != 0)
                        url = url + "&td=" + td;
                    app.Frame1.set("sourceUrl", url);
                    console.log("Error occured while loading the dialog: " + + ", " + exception.message + ", " + exception.stack)

  4. Set the hight and width as 100% (this does not work in Sitecore 8.2) to ensure that frame occupies the whole area of the dialogwindow component

    Frame component properties

  5. Set the Background style to static (to ensure that background is greyed and you cannot do anything until you respond to the dialog window)

    DialogWindow component properties

Hope this helps

Sunday, November 27, 2016

Installation Instructions for Sitecore QuartzScheduler Module

Installation Instructions for Sitecore QuartzScheduler module

Module works with Sitecore 8, 8.1 update 3. Tested it with 8.2 but apart from trigger detail dialog, everything seems to work. 
Please follow these steps to install the packages in a zip file

  1. Install TDS.Sitecore.QuartzScheduler.Core.update package
  2. Install TDS.Sitecore.QuartzScheduler.Matser.update package
  3. Re-build Master Index

  4. At this point you are ready to define your jobs and triggers

  5. Optional steps
    1. Install TDS.Sitecore.QuartzScheduler.Master.Content.update package to install out of the box job definitions
      Note: If you are installing this package, see notes below each job to ensure you don’t run it twice
    2. This package contains job definitions for:
      • HelloWorld demo job
      • Archive Job performance statistics
      • Cleanup Publish Queue (Sitecore job) - invoked from a quartz job
        • In Sitecore agent /task configuration, set interval to 00:00:00 to disable Sitecore invoking this job
      • Cleanup History (Sitecore job) - invoked from a quartz job
        • In Sitecore agent / task configuration, set interval to 00:00:00 to disable Sitecore invoking this job
      • Cleanup Event Queue (Sitecore job) - invoked from a quartz job
        • In Sitecore agent / task configuration, set interval to 00:00:00 to disable Sitecore invoking this job

    3. Restart App Pool
Add Log4Net configuration as mentioned below
Under <log4net> node, add appender for Sitecore.QuartzScheduler as shown below


Add corresponding logger just below </root> element, as shown below


Known issue with Sitecore 8.2
Trigger detail dialog does not take the whole window width and hight. This apperas to be Frame control issue.

Work around to this is you can open triggerdetail page by copying jobdetail and trigger detail id as given below


You can get the trigger detail and job detail id from job detail page. When you click on the trigger item in the list control, console shows you the id of the trigger, you can copy from there.