Full code

CustomMembershipProvider.cs

C#
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration.Provider;
using System.Linq;
using System.Web.Security;
using Telerik.Sitefinity.Data;
using Telerik.Sitefinity.Localization;
using Telerik.Sitefinity.Model;
using Telerik.Sitefinity.Security;
using Telerik.Sitefinity.Security.Data;
using Telerik.Sitefinity.Security.Model;
using SitefinityWebApp.Model;

namespace SitefinityWebApp.Providers
{
   /// <summary>
   /// Custom Membership Provider class
   /// </summary>
   public class CustomMembershipProvider : MembershipDataProvider
   {
       #region Privates variables
       private ManagerInfo managerInfo;
       private string providerName = "CustomMembershipProvider";
       private DateTime minDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
       #endregion

       #region Public variables
       public const string ServiceEndpointKey = "serviceEndpoint";
       #endregion

       #region Properties

       public CustomMembershipProviderEntities ProviderEntities { get; set; }

       public string ProviderName
       {
           get { return this.providerName; }
           set { this.providerName = value; }
       }

       public override string ApplicationName
       {
           get
           {
               return "/CustomMembershipProvider";
           }
       }

       private ManagerInfo ManagerInfo
       {
           get
           {
               return this.managerInfo ?? (this.managerInfo = new ManagerInfo()
               {
                   ProviderName = this.ProviderName,
                   ManagerType = "Telerik.Sitefinity.Security.UserManager",
                   ApplicationName = this.ApplicationName
               });
           }
       }

       /// <summary>
       /// Gets the provider abilities for the current principal. E.g. which operations are supported and allowed
       /// </summary>
       /// <value>The provider abilities.</value>
       public override ProviderAbilities Abilities
       {
           get
           {
               var abilities = new ProviderAbilities { ProviderName = Name, ProviderType = GetType().FullName };
               abilities.AddAbility("GetUser", true, true);
               abilities.AddAbility("AddUser", true, true);
               abilities.AddAbility("DeleteUser", true, true);
               abilities.AddAbility("UpdateUser", true, true);
               abilities.AddAbility("ValidateUser", true, true);
               abilities.AddAbility("ResetPassword", true, true);
               abilities.AddAbility("GetPassword", true, true);
               return abilities;
           }
       }

       #endregion

       #region Methods
       /// <summary>
       /// Create a new transaction
       /// </summary>
       /// <param name="transactionName"></param>
       /// <returns></returns>
       protected override object CreateNewTransaction(string transactionName)
       {
           return new object();
       }

       /// <summary>
       /// Commit the transaction
       /// </summary>
       public override void CommitTransaction()
       {
       }		/// <summary>
       /// Get items
       /// </summary>
       /// <returns></returns>	public override IEnumerable GetItems(Type itemType, string filterExpression, string orderExpression, int skip, int take, ref int? totalCount)	{		return base.GetItems(itemType, filterExpression, orderExpression, skip, take, ref totalCount);	}

       /// <summary>
       /// Get a new Guid
       /// </summary>
       /// <returns></returns>
       protected override Guid GetNewGuid()
       {
           return Guid.NewGuid();
       }

       /// <summary>
       /// Dispose
       /// </summary>
       /// <param name="disposing"></param>
       protected override void Dispose(bool disposing)
       {
           if (!disposing)
           {
               base.Dispose(false);
           }
       }

       /// <summary>
       /// Check if the password is valid
       /// </summary>
       /// <param name="user"></param>
       /// <param name="password"></param>
       /// <returns></returns>
       private bool CheckValidPassword(User user, string password)
       {
           if (user == null || !user.IsApproved || string.IsNullOrWhiteSpace(user.Password))
               return false;

           if (user.IsLockedOut)
           {
               var failedPasswordAttemptWindowStart = user.FailedPasswordAttemptWindowStart;
               if (DateTime.UtcNow <= failedPasswordAttemptWindowStart.AddMinutes((double)this.PasswordAttemptWindow))
               {
                   return false;
               }

               this.UnlockUser(user);
           }

           var passwordFormat = (MembershipPasswordFormat)user.PasswordFormat;
           return this.CheckValidPassword(string.Concat(password, user.Salt), user.Password, passwordFormat);
       }

       /// <summary>
       /// Check if the password is valid
       /// </summary>
       /// <param name="enteredByUser"></param>
       /// <param name="original"></param>
       /// <param name="passwordFormat"></param>
       /// <returns></returns>
       private bool CheckValidPassword(string enteredByUser, string original, MembershipPasswordFormat passwordFormat)
       {
           if (passwordFormat != MembershipPasswordFormat.Encrypted)
               return original == this.EncodePassword(enteredByUser, null, passwordFormat);

           var str = DecodePassword(original, passwordFormat);
           return str == enteredByUser;
       }

       /// <summary>
       /// Check if the EmailAddress already exits
       /// </summary>
       /// <param name="email"></param>
       /// <returns></returns>
       public override bool EmailExists(string email)
       {
           return this.ProviderEntities.Customers.SingleOrDefault(c => c.Email == email) != null;
       }

       /// <summary>
       /// Check if the Username already exits
       /// </summary>
       /// <param name="userName"></param>
       /// <returns></returns>
       public override bool UserExists(string userName)
       {
           return this.ProviderEntities.Customers.SingleOrDefault(c => c.Username == userName) != null;
       }

       /// <summary>
       /// Create a new Sitefinity User based on our Customer entity.
       /// This method is being used by: GetUsers(), GetUser()
       /// </summary>
       /// <param name="customer"></param>
       /// <returns></returns>
       private User GetSitefinityUser(Customer customer)
       {
           var user = new User
           {
               ApplicationName = this.ApplicationName,
               IsBackendUser = false,
               Id = customer.CustomerId,
               Email = customer.Email,
               Comment = string.Empty,
               LastActivityDate = DateTime.UtcNow.AddDays(-1),
               LastModified = minDate,
               LastLoginDate = minDate,
               FailedPasswordAnswerAttemptWindowStart = minDate,
               FailedPasswordAttemptWindowStart = minDate,
               Password = customer.Password,
               Salt = customer.Salt,
               ManagerInfo = ManagerInfo,
               IsApproved = customer.IsApproved,
               PasswordFormat = 2
           };

           user.SetUserName(customer.Username);
           user.SetCreationDate(DateTime.Now);
           user.SetIsLockedOut(false);
           user.SetLastLockoutDate(DateTime.Now);
           user.SetLastPasswordChangedDate(DateTime.Now);
           user.SetPasswordQuestion("question");

           return user;
       }

       /// <summary>
       /// Initializing
       /// </summary>
       /// <param name="providerName"></param>
       /// <param name="config"></param>
       /// <param name="managerType"></param>
       protected override void Initialize(string providerName, NameValueCollection config, Type managerType)
       {
           // Initialize a new instance of our Membership Provider Entity model
           this.ProviderEntities = new CustomMembershipProviderEntities();
           base.Initialize(providerName, config, managerType);
       }

       /// <summary>
       /// Get Users
       /// </summary>
       /// <returns></returns>
       public override IQueryable<User> GetUsers()
       {
           var customers = this.ProviderEntities.Customers;
           var users = new List<User>();

           foreach (var customer in customers)
           {
               var user = this.GetSitefinityUser(customer);
               users.Add(user);
           }

           return users.AsQueryable();
       }

       /// <summary>
       /// Get User by ID
       /// </summary>
       /// <param name="id"></param>
       /// <returns></returns>
       public override User GetUser(Guid id)
       {
           var customer = this.ProviderEntities.Customers.SingleOrDefault(c => c.CustomerId == id);
           return customer == null ? null : this.GetSitefinityUser(customer);
       }

       /// <summary>
       /// Get User by Email
       /// </summary>
       /// <param name="email"></param>
       /// <returns></returns>
       public override User GetUserByEmail(string email)
       {
           var customer = this.ProviderEntities.Customers.SingleOrDefault(c => c.Email == email);
           return customer == null ? null : this.GetSitefinityUser(customer);
       }

       /// <summary>
       /// Get User by Username
       /// </summary>
       /// <param name="userName"></param>
       /// <returns></returns>
       public override User GetUser(string userName)
       {
           var customer = this.ProviderEntities.Customers.SingleOrDefault(c => c.Username == userName);
           return customer == null ? null : this.GetSitefinityUser(customer);
       }

       /// <summary>
       /// Create a new User.
       /// </summary>
       /// <param name="username"></param>
       /// <param name="password"></param>
       /// <param name="email"></param>
       /// <param name="passwordQuestion"></param>
       /// <param name="passwordAnswer"></param>
       /// <param name="isApproved"></param>
       /// <param name="providerUserKey"></param>
       /// <param name="status"></param>
       /// <returns></returns>
       public override User CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
       {
           // First we validate the given parameters
           if (!this.ValidateParameters(ref username, ref password, ref email, ref passwordQuestion, ref passwordAnswer, ref providerUserKey, out status))
           {
               return null;
           }

           // Generate a new Salt
           var str = GenerateSalt();

           // Get a UTC DateTime
           var utcNow = DateTime.UtcNow;

           // Create a new user with the parameters entered from the Sitefinity backend
           var empty = this.CreateUser((Guid)providerUserKey, username);
           empty.Password = this.EncodePassword(password, str, this.PasswordFormat);
           empty.PasswordAnswer = this.EncodePassword(passwordAnswer.ToUpperInvariant(), null, this.PasswordFormat);
           empty.Salt = str;
           empty.Email = email;
           empty.Comment = string.Empty;
           empty.IsApproved = isApproved;
           empty.FailedPasswordAttemptCount = 0;
           empty.FailedPasswordAttemptWindowStart = utcNow;
           empty.FailedPasswordAnswerAttemptCount = 0;
           empty.FailedPasswordAnswerAttemptWindowStart = utcNow;
           empty.PasswordFormat = (int)PasswordFormat;
           empty.PasswordAnswer = passwordAnswer;
           empty.SetPasswordQuestion(passwordQuestion);
           empty.SetCreationDate(DateTime.Now);

           // Add the new user to the customer table in our custom database
           var customer = new Customer
           {
               CustomerId = empty.Id,
               Username = empty.UserName,
               Password = empty.Password,
               Salt = empty.Salt,
               IsApproved = empty.IsApproved,
               Email = empty.Email
           };

           // Save our changes
           this.ProviderEntities.Customers.Add(customer);
           this.ProviderEntities.SaveChanges();

           // Return our new Sitefinity User
           return empty;
       }

       /// <summary>
       /// Create a new User
       /// </summary>
       /// <param name="userName"></param>
       /// <returns></returns>
       public override User CreateUser(string userName)
       {
           return this.CreateUser(this.GetNewGuid(), userName);
       }

       /// <summary>
       /// Create a new User
       /// </summary>
       /// <param name="id"></param>
       /// <param name="userName"></param>
       /// <returns></returns>
       public override User CreateUser(Guid id, string userName)
       {
           if (id == Guid.Empty) throw new ArgumentNullException("id");

           if (!string.IsNullOrEmpty(userName))
           {
               LoginUtils.CheckParameter(userName, true, true, true, 256, "userName");
               if (this.UserExists(userName))
               {
                   throw new ProviderException("Username already exists.");
               }
           }

           var user = new User { ApplicationName = this.ApplicationName, Id = id };
           user.SetUserName(userName);
           ((IDataItem)user).Provider = this;
           user.ManagerInfo = ManagerInfo;

           return user;
       }

       /// <summary>
       /// Validate User
       /// </summary>
       /// <param name="userName"></param>
       /// <param name="password"></param>
       /// <returns></returns>
       public override bool ValidateUser(string userName, string password)
       {
           return this.ValidateUser(this.GetUser(userName), password);
       }

       /// <summary>
       /// Validate User
       /// </summary>
       /// <param name="user"></param>
       /// <param name="password"></param>
       /// <returns></returns>
       public override bool ValidateUser(User user, string password)
       {
           if (user == null) return false;

           var flag = this.CheckValidPassword(user, password);
           if (flag)
           {
               user.LastLoginDate = DateTime.UtcNow;
               user.FailedPasswordAttemptWindowStart = DateTime.UtcNow;
               user.FailedPasswordAttemptCount = 0;
           }
           else
           {
               this.UpdateFailureCount(user, "password");
           }

           return flag;
       }

       /// <summary>
       /// Delete User
       /// </summary>
       /// <param name="item"></param>
       public override void Delete(User item)
       {
           var customer = this.ProviderEntities.Customers.SingleOrDefault(c => c.Username == item.UserName);
           if (customer == null) return;

           this.ProviderEntities.Customers.Remove(customer);
           this.ProviderEntities.SaveChanges();
       }

       /// <summary>
       /// Get Password
       /// </summary>
       /// <param name="user"></param>
       /// <param name="answer"></param>
       /// <returns></returns>
       public override string GetPassword(User user, string answer)
       {
           if (!this.EnablePasswordRetrieval)
               throw new ProviderException(Res.Get<ErrorMessages>().PasswordRetrievalNotEnabled);

           if (user == null) throw new ProviderException(Res.Get<ErrorMessages>().MembershipUserNotFound);

           var passwordFormat = (MembershipPasswordFormat)user.PasswordFormat;
           if (passwordFormat == MembershipPasswordFormat.Hashed)
               throw new ProviderException(Res.Get<ErrorMessages>().CannotRetrieveHashedPasswords);

           if (user.IsLockedOut) throw new ProviderException(Res.Get<ErrorMessages>().MembershipUserLocked);

           if (this.RequiresQuestionAndAnswer)
           {
               if (!string.IsNullOrEmpty(answer))
               {
                   var passwordAnswer = user.PasswordAnswer;
                   if (!this.CheckValidPassword(answer.Trim().ToUpperInvariant(), passwordAnswer, passwordFormat))
                   {
                       this.UpdateFailureCount(user, "answer");
                       throw new ProviderException(Res.Get<ErrorMessages>().WrongPasswordAnswer);
                   }
               }
               else
               {
                   this.UpdateFailureCount(user, "answer");
                   throw new ProviderException(Res.Get<ErrorMessages>().PasswordAnswerRequired);
               }
           }

           var salt = user.Salt;
           var str = DecodePassword(user.Password, passwordFormat);
           return str.Left(str.Length - salt.Length);
       }

       /// <summary>
       /// Get Password
       /// </summary>
       /// <param name="userName"></param>
       /// <param name="answer"></param>
       /// <returns></returns>
       public override string GetPassword(string userName, string answer)
       {
           return this.GetPassword(this.GetUser(userName), answer);
       }

       /// <summary>
       /// Get Password
       /// </summary>
       /// <param name="userId"></param>
       /// <param name="answer"></param>
       /// <returns></returns>
       public override string GetPassword(Guid userId, string answer)
       {
           return this.GetPassword(this.GetUser(userId), answer);
       }

       /// <summary>
       /// Reset the password
       /// </summary>
       /// <param name="user"></param>
       /// <param name="answer"></param>
       /// <returns></returns>
       public override string ResetPassword(User user, string answer)
       {
           if (this.EnablePasswordReset)
           {
               if (user != null)
               {
                   var passwordFormat = (MembershipPasswordFormat)user.PasswordFormat;
                   if (!user.IsLockedOut)
                   {
                       if (this.RequiresQuestionAndAnswer)
                       {
                           if (!string.IsNullOrEmpty(answer))
                           {
                               string passwordAnswer = user.PasswordAnswer;
                               if (!this.CheckValidPassword(answer.Trim().ToUpperInvariant(), passwordAnswer, passwordFormat))
                               {
                                   this.UpdateFailureCount(user, "answer");
                                   throw new ProviderException(Res.Get<ErrorMessages>().WrongPasswordAnswer);
                               }
                           }
                           else
                           {
                               this.UpdateFailureCount(user, "answer");
                               throw new ProviderException(Res.Get<ErrorMessages>().PasswordAnswerRequired);
                           }
                       }

                       string str = System.Web.Security.Membership.GeneratePassword(this.NewPasswordLength, this.MinRequiredNonAlphanumericCharacters);
                       string salt = user.Salt;
                       string str1 = this.EncodePassword(str, salt, passwordFormat);
                       user.SetLastPasswordChangedDate(DateTime.UtcNow);
                       var customer = this.ProviderEntities.Customers.SingleOrDefault(c => c.CustomerId == user.Id);
                       customer.Password = str1;
                      
                       return str;
                   }
                   else
                   {
                       throw new ProviderException(Res.Get<ErrorMessages>().MembershipUserLocked);
                   }
               }
               else
               {
                   throw new ProviderException(Res.Get<ErrorMessages>().MembershipUserNotFound);
               }
           }
           else
           {
               throw new NotSupportedException(Res.Get<ErrorMessages>().PasswordResetIsNotEnabled);
           }
       }

       /// <summary>
       /// Reset the password
       /// </summary>
       /// <param name="userName"></param>
       /// <param name="answer"></param>
       /// <returns></returns>
       public override string ResetPassword(string userName, string answer)
       {
           return this.ResetPassword(this.GetUser(userName), answer);
       }

       /// <summary>
       /// Reset the password
       /// </summary>
       /// <param name="userId"></param>
       /// <param name="answer"></param>
       /// <returns></returns>
       public override string ResetPassword(Guid userId, string answer)
       {
           return this.ResetPassword(this.GetUser(userId), answer);
       }
       #endregion

       #region Not Supported

       public override bool ChangePassword(User user, string oldPassword, string newPassword)
       {
           base.ChangePassword(user, oldPassword, newPassword);
           MembershipPasswordFormat passwordFormat = (MembershipPasswordFormat)user.PasswordFormat;
           var customer = this.ProviderEntities.Customers.SingleOrDefault(c => c.CustomerId == user.Id);
           customer.Password = this.EncodePassword(newPassword, user.Salt, passwordFormat);

           return true;
       }
       #endregion
   }
}
Want to learn more?
Enhance your Sitefinity skills by enrolling in free training sessions. Become Sitefinity certified through Progress Education Community to strengthen your professional credentials.
New to Sitefinity?