[Kentico 9] How to allow E-Mail and Username authentication at the same time.

Saurav Kumar asked on August 10, 2016 10:13

I was trying to find out a way I can enable Username login as well as E-Mail login.
I did find some links for Kentico 7 & below but none for Kentico 9.
There was a difference in the implmentation and the solution didn't work out for Kentico 9 as we don't have CMSAppBase.cs in Kentico 8 & above.
The links to the earlier examples are this and this.

Correct Answer

Saurav Kumar answered on August 10, 2016 10:31

I just wanted to list out the implementation for Kentico 9.
Its a combined solution from the links in the question as well as from Michal Samuhel - Kentico Support.

You need to override the MembershipProvider and also the UserInfoProvider by registering a custom provider.

1) First Create a class CustomMembershipProvider.cs and override the ValidateUser method.

using CMS.Helpers;
using CMS.Membership;
using CMS.MembershipProvider;
using CMS.SiteProvider;

/// <summary>
/// Summary description for CustomMembershipProvider
/// </summary>
public class CustomMembershipProvider : CMSMembershipProvider
{
    public override bool ValidateUser(string username, string password)
    {
        if (ValidationHelper.IsEmail(username))
        {
            var customUsername = base.GetUserNameByEmail(username);

            if (!string.IsNullOrEmpty(customUsername))
                username = customUsername;
        }
        return base.ValidateUser(username, password);
    }
}

2) Now we need to specify this CustomMembershipProvider in the web.config file

Find out the membership node like below and replace the "type" value to "CustomMembershipProvider"

<membership defaultProvider="CMSProvider" userIsOnlineTimeWindow="30">
      <providers>
        <clear />
        <add name="CMSProvider" type="CustomMemershipProvider" connectionStringName="CMSConnectionString" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Hashed" />      
     </providers>
</membership>

3) Now we need to register the CustomUserInfoProvider as below. Create a class CustomUserInfoProvider.cs

using CMS.Helpers;
using CMS.Membership;
using CMS.MembershipProvider;

[assembly: CMS.RegisterCustomProvider(typeof(CMSModuleLoader.CustomUserInfoProvider))]
public partial class CMSModuleLoader
{
    /// <summary>
    /// Summary description for CustomUserInfoProvider
    /// </summary>
    public class CustomUserInfoProvider : UserInfoProvider
    {
        protected override UserInfo GetUserInfoInternal(string userName)
        {
            if (ValidationHelper.IsEmail(userName))
            {
                CMSMembershipProvider membershipProvider = new CMSMembershipProvider(); 
                string customUserName = membershipProvider.GetUserNameByEmail(userName);

                if (!string.IsNullOrEmpty(customUserName))
                    userName = customUserName;
            }
            return base.GetUserInfoInternal(userName);
        }
    }
}

That marks it done.
P.S. This code will be global and will also help to login into the CMSDesk with your E-Mail. However you can modify using your SiteName in the code to be site specific.

Regards,
Saurav Kumar

2 votesVote for this answer Unmark Correct answer

Recent Answers


Roman Hutnyk answered on August 10, 2016 10:30

I'd do that like suggested here, but in the SecurityEvents.Authenticate.Execute event (more details here):

private void OnAuthentication(object sender, AuthenticationEventArgs e)
{        
    if (e.User == null)
    {
        if (ValidationHelper.IsEmail(e.UserName))
        {
            string name = GetUserNameByEmail(e.UserName);
            if (CMSMembershipProvider.ValidateUser(name, e.Password))
            {
                e.User = UserInfoProvider.GetUserInfo(e.UserName);
            } 
        }
    }
}
0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.