Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Johan 6 posts 86 karma points
    Oct 31, 2019 @ 10:05
    Johan
    0

    Custom membership provider in Umbraco 8

    Hello Umbracoland

    I want to move my members from the umbraco database to another database, where the members will be stored. I need to implement my own membership provider, as I want to hash everything we know about our users.

    Untill now I have just been trying to very simple membership provider to store some mock users in a local database. I have so far based my solution on an earlier post (https://our.umbraco.com/forum/developers/extending-umbraco/74219-custom-membership-provider/), however I am using the Entity framework instead.

    So far I have

    • Created a custom membership provider inheriting from the standard membership provider.
    • Made a member repository with methods for interactions with the database.
    • Made a model class with an entity framework class.
    • Replaced the default umbraco membership provider with my custom membership provider in the Web.config file.

    When I try to create a member in the backoffice -> Members -> Members -> create I get an error message. To me it seems that Umbraco doesn't recognize my membership provider. I hope someone out there is able to helpt me, I've been stuck with this for quite some time now.

    Error message

    System.NullReferenceException: Object reference not set to an instance of an object.

    Stacktrace

    at Umbraco.Web.Models.Mapping.MemberTabsAndPropertiesMapper.Map(IMember source, MapperContext context) at Umbraco.Web.Models.Mapping.MemberMapDefinition.Map(IMember source, MemberDisplay target, MapperContext context) at Umbraco.Core.Mapping.UmbracoMapper.<>c_DisplayClass802.<Define>b__1(Object source, Object target, MapperContext context) at Umbraco.Core.Mapping.UmbracoMapper.Map[TTarget](Object source, Type sourceType, MapperContext context) at Umbraco.Core.Mapping.UmbracoMapper.Map[TTarget](Object source, MapperContext context) at Umbraco.Web.Editors.MemberController.GetEmpty(String contentTypeAlias) at lambda_method(Closure , Object , Object[] ) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_2.<GetExecutor>b__2(Object instance, Object[] methodParameters) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary2 arguments, CancellationToken cancellationToken)

    My code

    CustomMemberhipProvider.cs

    public class CustomMembershipProvider : MembershipProvider
    {
        private string _applicationName = "UmbracoMembershipProvider";
    
        public override string ApplicationName {
            get { return _applicationName; }
            set
            {
                if (string.IsNullOrEmpty(value))
                    throw new ProviderException("ApplicationName cannot be empty");
                if (value.Length > 0x100)
                    throw new ProviderException("Provider application name too long");
                _applicationName = value;
            }
        }
      public override void Initialize(string name, NameValueCollection config)
        {
            base.Initialize(name, config);
        }
    
    
        public override bool EnablePasswordRetrieval => false;
    
        public override bool EnablePasswordReset => false;
    
        public override bool RequiresQuestionAndAnswer => false;
    
        public override int MaxInvalidPasswordAttempts => throw new NotImplementedException();
    
        public override int PasswordAttemptWindow => throw new NotImplementedException();
    
        public override bool RequiresUniqueEmail => true;
    
        public override MembershipPasswordFormat PasswordFormat => MembershipPasswordFormat.Hashed;
    
        public override int MinRequiredPasswordLength => 6;
    
        public override int MinRequiredNonAlphanumericCharacters => 0;
    
        public override string PasswordStrengthRegularExpression => throw new NotImplementedException();
    
        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            throw new NotImplementedException();
        }
    
        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
        {
            throw new NotImplementedException();
        }
    
        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            var memberRepository = new MembersRepository();
            bool memberCreated = memberRepository.CreateUser(username, email, password);
                MembershipUser newMember = new MembershipUser(
                "UmbracoMembershipProvider",
                username,
                providerUserKey,
                email,
                passwordQuestion,
                "",
                isApproved,
                false,
                DateTime.Now,
                DateTime.Now,
                DateTime.Now,
                DateTime.Now,
                DateTime.Now
                );
            if( memberCreated)
            {
                status = MembershipCreateStatus.Success;
                return newMember;
    
            }
            status = MembershipCreateStatus.ProviderError;
            return null;
        }
    
        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            var memberRepository = new MembersRepository();
            return memberRepository.DeleteUser(username);
        }
    
        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }
    
        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();   
        }
    
        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }
    
        public override int GetNumberOfUsersOnline()
        {
            throw new NotImplementedException();
        }
    
        public override string GetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }
    
        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            var repos = new MembersRepository();
            MockUserClass member = repos.GetUserById( (Guid)providerUserKey );
            if (member != null)
                return ConvertToMembershipUser(member);
            return null;
        }
    
        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            var repos = new MembersRepository();
            var member = repos.GetUserByName(username);
            if (member != null)
            {
                return ConvertToMembershipUser(member);
            }
            return null;
        }
    
        public override string GetUserNameByEmail(string email)
        {
            var repos = new MembersRepository();
            return repos.GetUserNameByEmail(email);
        }
    
        public override string ResetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }
    
        public override bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }
    
        public override void UpdateUser(MembershipUser user)
        {
            throw new NotImplementedException();
        }
    
        public override bool ValidateUser(string username, string password)
        {
            var repos = new MembersRepository();
            MockUserClass member = repos.GetUserByName(username);
            if(member != null)
            {
                if (member.Password == password)
                    return true;
            }
            return false;
        }
    
        private MembershipUser ConvertToMembershipUser(MockUserClass member)
        {
            return new MembershipUser("UmbracoMembershipProvider", member.Username, member.Id, member.Email, "", "", member.IsApproved, member.IsLockedOut, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.MinValue, DateTime.MinValue);
        }
    
        private MembershipUserCollection GetMembershipUserCollection(IEnumerable<MockUserClass> queryResult)
        {
            var Members = new MembershipUserCollection();
            foreach (var member in queryResult)
            {
                Members.Add(ConvertToMembershipUser(member));
            }
            return Members;
        }
    }
    

    MembersRepository.cs

    public class MembersRepository
    {
    
        public bool CreateUser(string username,string email, string password)
        {
            using (var context = new UserDb())
            {
                var newMember = new MockUserClass(
                username,
                password,
                email
                );
                context.Members.Add(newMember);
                return true;
            };
    
        }
    
        public bool DeleteUser(string username)
        {
            using (var context = new UserDb())
            {
                var member = (from m in context.Members
                              where m.Username == username
                              select m).FirstOrDefault();
                if (member != null)
                {
                    context.Members.Remove(member);
                    return true;
                }
                return false;
            }
    
        }
        public MockUserClass GetUserById(Guid id)
        {
            using (var context = new UserDb())
            {
                var member = (from m in context.Members
                              where m.Id == id
                              select m).FirstOrDefault();
                return member;
            }
        }
        public MockUserClass GetUserByName(string name)
        {
            using (var context = new UserDb())
            {
                var member = (from m in context.Members
                              where m.Username == name
                              select m).FirstOrDefault();
                return member;
            }
        }
    
        public string GetUserNameByEmail(string email)
        {
            using (var context = new UserDb())
            {
                var username = (from member in context.Members
                                where member.Email == email
                                select member.Username).FirstOrDefault();
                return username;
            }
        }
    }
    

    Entity framework class

    public class UserDb : DbContext
    {
        public UserDb():base("name=UserDb"){}
        public DbSet<MockUserClass> Members { get; set; }
    }
    

    Snippets from web.config

    <connectionStrings>
    <remove name="umbracoDbDSN" />
    // umbraco database connection, removed for clarity
    <add name="UserDb" connectionString="Data Source=PF1PXX7N\SQLEXPRESS;Initial Catalog=MockUserDatabase;Integrated Security=True" providerName="System.Data.SqlClient" />
    

    <providers>
        <clear />
        <add name="UmbracoMembershipProvider" type="UserProject.Classes.CustomMembershipProvider, UserProject" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="8" useLegacyEncoding="true" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="Member" passwordFormat="Hashed"/>
        <add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco.Web" />
      </providers>
    </membership>
    
  • Ian 178 posts 752 karma points
    Nov 04, 2019 @ 14:14
    Ian
    100

    Hi Johan what does your MockUserClass look like? Does it implement the IMember interface which the Umbraco mapper looks to be expecting?

  • Johan 6 posts 86 karma points
    Nov 04, 2019 @ 14:55
    Johan
    0

    Hi Ian

    No it does not! I will try to implement it and return with a result.

  • Johan 6 posts 86 karma points
    Nov 04, 2019 @ 15:26
    Johan
    0

    I think this has solved my problem, now I just need to figure out what to implement! thank you so much!

  • Ion Cracea 12 posts 93 karma points
    Mar 06, 2020 @ 16:44
    Ion Cracea
    0

    Hi, do you still remember how exactly you solved the problem? I.ve implemented the IMember interface but that hasn't worked anyway. An example code would be much appreciated. Thank you.

  • Jay 425 posts 652 karma points
    Jun 29, 2023 @ 10:48
    Jay
    0

    I am looking to do something similar. Appreciate if there's any sharing on this. thanks

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies