Monday, May 12, 2014

Sitecore Security: Password Expiration and Strengthen Customization



Here I am sharing some sort of sitecore login-Password customization.
Attached document explain how to enforce password expiration and Password strengthen customization in sitecore.


Feel free to contact me for any further query or assistant on the same.


For strengthen the site core user password

Below is the solution of password strengthen requirement
·         Password At least 1 small-case letter.
·         Password  At least 1 Capital letter.
·         Password  At least 1 digit.
·         Password At least 1 special character.
·         Password  Length should be between 8-30 characters.
·         Spaces allowed.
·         The sequence of the characters is not important.

There are two way to resolve this
Through REGEX: there is setting in webconfig where we can easily update the password strengthen
passwordStrengthRegularExpression="(?=^.{8,30}$)(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()_+}{"":;'?/>.<,]).*$".

This is same regex for above requirement.
Through Kernal.Client.SetPasswordPage Customization:
Go to sitecore\shell\Applications\Security\SetPassword\SetPassword.Xaml.xml
Override the Sitecore.Client dll file named
SetPasswordPage.cs(Sitecore.Shell.Applictions.Security.SetPassword) with your desired password validation.

Note: for changepassword.aspx we can achieve this by ClientSide Validation.















For Enforcing the Password Expiration:

Create class below
using System;
using System.Web.Security;
using Sitecore.Diagnostics;
using Sitecore.Pipelines.LoggingIn;
using Sitecore.Web;
using Sitecore.Security.Authentication;


namespace CommonBusiness
{
    public class CheckPasswordExpiration
    {
        private TimeSpan TimeSpanToExpirePassword { get; set; }
        private string  TimeSpanToLastLoginForExistingUser { get; set; }
        private string ChangePasswordPageUrl { get; set; }

        public void Process(LoggingInArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            if (!IsEnabled())
            {
                return;
            }
            MembershipUser user = GetMembershipUser(args);
            AuthenticationHelper authenticationHelper = new AuthenticationHelper(AuthenticationManager.Provider);
            if (!string.IsNullOrEmpty(args.Username) && !string.IsNullOrEmpty(args.Password) && authenticationHelper.ValidateUser(args.Username, args.Password))
            {
                if (HasPasswordExpired(user))
                {
                    WebUtil.Redirect(ChangePasswordPageUrl);
                }
            }
        }

        private bool IsEnabled()
        {
            return IsTimeSpanToExpirePasswordSet() && IsChangePasswordPageUrlSet();
        }

        private bool IsTimeSpanToExpirePasswordSet()
        {
            return TimeSpanToExpirePassword > default(TimeSpan);
        }

        private bool IsChangePasswordPageUrlSet()
        {
            return !string.IsNullOrWhiteSpace(ChangePasswordPageUrl);
        }

        private static MembershipUser GetMembershipUser(LoggingInArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            Assert.ArgumentNotNullOrEmpty(args.Username, "args.Username");
            return Membership.GetUser(args.Username, false);
        }

        private bool HasPasswordExpired(MembershipUser user)
        {
            if (string.IsNullOrEmpty(TimeSpanToLastLoginForExistingUser) == false)
            {
                DateTime deploymentDate = DateTime.ParseExact(TimeSpanToLastLoginForExistingUser, "yyyy-MM-dd HH:mm:ss,fff",
                                        System.Globalization.CultureInfo.InvariantCulture);
                if (deploymentDate > user.LastPasswordChangedDate)
                {
                    return true;
                }
            }
            return user.LastPasswordChangedDate.Add(TimeSpanToExpirePassword) <= DateTime.Now;
        }
    }
}



















And update the config file to execute the above code before

Sitecore.Pipelines.LoggingIn.CheckStartPage


Below is the snippet of configuration file

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <processors>
      <loggingin>
        <processor mode="on" type="CommonBusiness.CheckPasswordExpiration, CommonBusiness"
                    patch:before="processor[@type='Sitecore.Pipelines.LoggingIn.CheckStartPage, Sitecore.Kernel']">
          <!-- Number of days, hours, minutes and seconds after the last password change date to expire passwords -->
          <TimeSpanToExpirePassword>05:00:01:00</TimeSpanToExpirePassword>
          <!--create date time 2008-03-09 16:05:07.123-->
          <!--year-Month-Day Hours-Min-Sec,Miile-->
          <TimeSpanToLastLoginForExistingUser>2011-05-08 14:36:52,531</TimeSpanToLastLoginForExistingUser>
          <ChangePasswordPageUrl>/sitecore/login/changepassword.aspx?isPasswordExpire=true</ChangePasswordPageUrl>
        </processor>
      </loggingin>
    </processors>
  </sitecore>
</configuration>