aspnet / Identity

[Archived] ASP.NET Core Identity is the membership system for building ASP.NET Core web applications, including membership, login, and user data. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
1.96k stars 868 forks source link

UserManager -> SetPasswordHashAsync is called before CreateAsync(user) #1865

Closed dm-CaT closed 6 years ago

dm-CaT commented 6 years ago

Is there any reason why when the new user is created with password the password hash is set before user is saved? I'm trying to implement my own IUserStore/IUserPasswordStore (to use custom DAL). But I got an error because my store cannot set password hash (update record in DB) to non created user. Here is the code from UserManager which causes an error.

        public virtual async Task<IdentityResult> CreateAsync(TUser user, string password)
        {
            ThrowIfDisposed();
            var passwordStore = GetPasswordStore();
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }
            if (password == null)
            {
                throw new ArgumentNullException(nameof(password));
            }
            // Here is the SetPasswordHashAsync occurs
            var result = await UpdatePasswordHash(passwordStore, user, password);
            if (!result.Succeeded)
            {
                return result;
            }
            // Only here I save user in DB
            return await CreateAsync(user);
        }

Link on method

HaoK commented 6 years ago

So Create/Update are the methods that actually persist the user, so updates to the poco need to happen before those methods are called to persist the user

dm-CaT commented 6 years ago

Can you point me for some correct example how to implement custom UserStore?

HaoK commented 6 years ago

The general idea is that Update/Create/Delete are the only methods that should persist to the backing store. All of the other methods should only be manipulating the user/role.

dm-CaT commented 6 years ago

This case I need to have PasswordHash property for user class. It looks not so good, because I want to have possibility to pass user objects anywhere I need without sensitive information like PasswordHash. Even if it's hash.

HaoK commented 6 years ago

You can store it somewhere else, it doesn't have to be a property on the user class

dm-CaT commented 6 years ago

I tried to go this way but I cannot. I have to link password hash with user it belongs to, e.g. store it with user id. But when I have hash to store I do not have user id yet. That's my problem.

HaoK commented 6 years ago

You will probably have to plug in a custom UserManager that switches the order of operations and CreateUser and then UpdatePasswordHash in your situation

HaoK commented 6 years ago

Or maybe just use the username as the foreign key assuming you don't let people change that

dm-CaT commented 6 years ago

User name as FK is not a choice. Looks like I have to implement a custom UserManager.

aspnet-hello commented 6 years ago

We periodically close 'discussion' issues that have not been updated in a long period of time.

We apologize if this causes any inconvenience. We ask that if you are still encountering an issue, please log a new issue with updated information and we will investigate.