Monday, March 27, 2017

Solr Basic Authentication : Secure through key vault

If you are using key vault and you want to secure solr basic authentication credential, it is good practice to fetch it from appsettings which will retrieve from key vault server for specific environment at runtime. In order to do that you may have to configure solr configuration programmatically. Below is the useful sitecore stackexchange link that can come handy.



http://sitecore.stackexchange.com/questions/5112/how-to-initialize-solr-end-point-connection-with-basic-authentication-programmat/5145#5145

namespace MyClassLibrary
{
  public class MyBasicAuthHttpWebRequestFactory : IHttpWebRequestFactory
  {


    public MyBasicAuthHttpWebRequestFactory(string username, string password)
    {
      this.username = ConfigurationManager.AppSettings["username"];
      this.password = ConfigurationManager.AppSettings["password"];
    }

    public IHttpWebRequest Create(string url)
    {
      return this.Create(new Uri(url));
    }

    public IHttpWebRequest Create(Uri url)
    {
      HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
      string base64String = Convert.ToBase64String(Encoding.ASCII.GetBytes(this.username + ":" + this.password));
      request.Headers.Add("Authorization", "Basic " + base64String);
      return (IHttpWebRequest) new HttpWebRequestAdapter(request);
    }
  }
}

http://sitecore.stackexchange.com/questions/5062/update-the-sitecore-configs-at-runtime-possible/5076#5076

Tuesday, March 21, 2017

Devops Cheat sheet

Try new Continuous Delivery Preview:




Scan your build with Whitesource for open source code base.

https://blogs.msdn.microsoft.com/visualstudioalm/2017/03/07/open-source-scanning-in-visual-studio-team-services-with-whitesource-bolt/

Build


Release Pipeline: 

Environment:

Set Pre-approval or post approval before someone deploy the release into test or prod.


Sitecore Active Directory:SitecoreADMembershipProvider Initialize and add provider at runtime in application_start

Key : Know and how

These are the following set of queries may be asked once we able to roll out , design or implement sitecore ldap module.

  • Whether Membership, role or profile provider required. Choose wisely, if membership is required just use that. 
  • The project requirement might be to use sitecore custom or out box role so active directory ldap role might not be worth to include.
  • Ensure you don't allow admin to action delete , edit of active directory users from sitecore. This may have implications. The rational: There could be service account or group created for content author and administrator user will be different from centralized security team. Let one team handle the removal of users from active directory server rather handle through sitecore.(Ensure you give read only permission to service account that is created in active directory server) This will allow one direction add and delete of users. This will help avoid accidental deletion from sitecore.
  • Understand Role and profile provider does not support SSL whereas membership support SSL only when it is trusted and known. (Need to explore more.) Therefore sometimes port 636 will not accept ssl certificate however sign and seal options are available with port 389 check ConnectionProtection attribute of LightLdap SitecoreAdMembership membership provider., the LDAPS connection should use a certificate which is properly validated by a Root CA:
  • This should be validated as per environment ‘sign-and-seal’ only works if the client (Web App VM) is on the same domain as the Server (AD Domain Controller) .Check below article web post by microsoft.
  • Consider credentials to be stored in key vault for azure environment. Downside the ldap membership provider of sitecore stores it in custom configuration unlike connectionstring or appsettings. For this to overcome you have to configure and initialize the sitecore membership provider at runtime in Application_start. I have given some reference code block to help you get around this.

https://social.technet.microsoft.com/wiki/contents/articles/2980.ldap-over-ssl-ldaps-certificate.aspx


Anton Jason, Has helped me with below solution reference. Later it helped me integrate this further.



Remember to add reference LightLdap.dll

public class ApplicationStartup
{
      
        public static void Startup()
        {
           
        }

        public virtual void Process(object args)
        {          
                SitecoreADMembershipProvider provider = new SitecoreADMembershipProvider();
                NameValueCollection config = new NameValueCollection();
                SitecoreADMembershipProvider provider = new SitecoreADMembershipProvider();
                 NameValueCollection config = new NameValueCollection();
                 // Configure your provider here. 
                 config["type"] = "LightLDAP.SitecoreADMembershipProvider";
                 config["name"] = "SomeProviderName";
 
                 config["connectionStringName"] = "LDAPConnString";
                 config["applicationName"] = "sitecore";
 
                 config["connectionUsername"] = ConfigurationManager.AppSettings["AppSettingKeys-UserName"];
                 config["connectionPassword"] = ConfigurationManager.AppSettings["AppSettingKeys-Password"];
 
                 config["minRequiredPasswordLength"] = "1";
                 config["minRequiredNonalphanumericCharacters"] = "0";
                 config["requiresQuestionAndAnswer"] = "false";
 
                 config["requiresUniqueEmail"] = "false";
                 config["connectionProtection"] = "secure";
 
                 config["attributeMapUsername"] = "sAMAccountName";
                 config["enableSearchMethods"] = "true";
 
                 config["customFilter"] = "(memberOf=Your org custom filter)";
 
                 provider.Initialize("SomeProviderName", config);
                 provider.AddTo(Membership.Providers);
        }
}

I used jetbrains dotpeek to look into sitecore LightLdap and it helped me understand how sitecore has created a custom wrapper
to implement its membership, role and profile.

Remember one thing there is struct MembershipProviderSettings which has all the above configuration defined.
This is protected if you planning to extend create custom class and inherit SitecoreADMembership provider. This is the only way out.


namespace LightLDAP
{
  public class SitecoreADMembershipProvider : MembershipProvider
  {
    protected bool initialized;
    protected MembershipProviderSettings settings;
    protected PartialDataSource source;

    public override string ApplicationName { get; set; }


    public SitecoreADMembershipProvider()
      : this((IAdMembershipProvider) new AdMembershipProvider())
    {
    }

    public SitecoreADMembershipProvider(IAdMembershipProvider innerProvider)
    {
      this.InnerProvider = innerProvider;
      this.settings = new MembershipProviderSettings();
    }

    public override void Initialize(string name, NameValueCollection config)
    {
      try
      {
        this.ApplicationName = config["applicationName"];
        this.settings.Initialize(config);
        config.Remove("serverPageTimeLimit");
        config.Remove("useNotification");
        try
        {
          bool isInnerFailed = false;
          try
          {
            this.InnerProvider.Initialize(name, config);
          }
          catch (Exception ex)
          {
            isInnerFailed = true;
          }
          try
          {
            this.settings.InitializeHidden(this.InnerProvider, isInnerFailed);
            this.source = DataStorageContainer.GetPartialSource(this.settings.AdsPath, this.settings.UserName, this.settings.Password, this.settings.AttributeMapUsername, this.settings.UseNotification);
            this.initialized = true;
          }
          catch (Exception ex)
          {
          }
          base.Initialize(name, config);
        }
        catch (Exception ex)
        {
          Log.Error("The AD membership provider couldn't be initialized: " + ex.Message, ex, (object) this);
        }
      }
      catch (Exception ex)
      {
        Log.Error("AD:", ex, (object) this);
        throw;
      }
    }
  }
}

Thursday, March 16, 2017

Sitecore Active Directory 1.3 Bug Reported: ProviderStatus throws error Unable to cast object of type 'Sitecore.Support.Security.SwitchingMembershipProvider' to type 'Sitecore.Security.SwitchingMembershipProvider'.

When you installed and setup Sitecore Active directory module 1.3 for update 8.2.1 it will throw below error. We reported this bug with sitecore support and they came up with required fix.


https://kb.sitecore.net/articles/520134

Tuesday, March 14, 2017

Sitecore Best Practice Avoid using sitecore intrinsic Controller name and action

Conflict with Sitecore Controller name: Multiple controller with same name

Avoid using AuthenticationController, HomeController and something more relevant to sitecore.

https://community.sitecore.net/developers/f/8/t/1634

This is the case when you are done with your development and you have enough time to check the event , iis and sitecore logs to cleanup your solution to meet good code and performance bench mark. Do consider this check before you come to this stage of clean-up. This will save time. I understand its cloud and such error doesn't matter. However its good to have less warnings in your logs. This will help you drill down to most critical error in production defects.

Having said that , scrutinize your logs during development using sitecore  log viewer or analyzer.