17

I have been given the requirement to provide the ability to create users through the UI with no password. I am trying to accomplish this using ASP.NET Identity.

I am able to successfully create a user without a password using the UserManager's Create method:

if (vm.ShouldHavePassword)
{
    userManager.Create(userToInsert, vm.Password);
}
else
{
    userManager.Create(userToInsert);
}

After the call to the Create method, the test user gets successfully saved into our AspNetUsers table. And when I do not provide a password, the PasswordHash column in our AspNetUsers table is set to NULL.

My issue is, I cannot login as the test user that does not have a password. The following is the method call that we use to validate a user's credentials:

result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);

I attempted to login as a test user that has a NULL PasswordHash multiple times. To do this, I do not provide a password in our login form. As a result, a NULL password is passed into the PasswordSignInAsync method. The return value of this method call is always SignInStatus.Failure.

Using ASP.NET Identity, how can I configure my code to correctly authenticate user credentials when the credentials contain a NULL password, and the user in the database contains a NULL PasswordHash? Is such a thing even possible?

4
  • Possible duplicate and / or solution stackoverflow.com/questions/28110934/… Commented Nov 19, 2015 at 20:27
  • I've already seen that question. What he was asking was how can I log in as any user without having to provide a password. What I'm asking is how can I login as a specific user that does not have a password saved in the database. Commented Nov 19, 2015 at 20:31
  • Understood. Did you try the code that he posted? FindByNameAsync and SignInAsync? Commented Nov 19, 2015 at 20:34
  • I certainly could use that code, but I would have to provide some logic to verify that this specific user's password in the database is set to NULL first, otherwise I would be able to login as any user without providing a password. And I don't want to have to provide that logic, because SignInManager already takes care of that for me. Commented Nov 19, 2015 at 20:38

4 Answers 4

14

Okay, what you need to do is find the user (AspNetUsers user) using your db context. After you have the user, you can check if their PasswordHash is null. If yes, then just sign them in using SignInManager.SignIn. If not, use SignInManager.PasswordSignIn.

example..

//alternatively, you can find the user using Email, Id or some other unique field
var user = db.AspNetUsers.FirstOrDefault(p => p.UserName); 
if (user != null)
{
    if (user.PasswordHash == null)
        await SignInManager.SignInAsync(user, true, true);
    else
        await SignInManager.PasswordSignInAsync(model.UserName, model.Password, 
            model.RememberMe, shouldLockout: false);
}

Hope it helps.

Sign up to request clarification or add additional context in comments.

Comments

14

Yes you can. ASP.NET Identity Framework is fully customizable. Just override PasswordValidator.ValidateAsync and PasswordHasher.VerifyHashedPassword methods like this:

internal class CustomPasswordValidator: PasswordValidator
{
    public override async Task<IdentityResult> ValidateAsync(string item)
    {
        if (string.IsNullOrEmpty(item)) return IdentityResult.Success;
        return await base.ValidateAsync(item);
    }
}

internal class CustomPasswordHasher : PasswordHasher
{
    public override PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword)
    {
        if (hashedPassword == null && string.IsNullOrEmpty(providedPassword))
            return PasswordVerificationResult.Success;
        return base.VerifyHashedPassword(hashedPassword, providedPassword);
    }
}

And set them like this:

    var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));

    manager.PasswordValidator = new CustomPasswordValidator();
    manager.PasswordHasher = new CustomPasswordHasher();

Comments

1

I often need to create the first admin user of the system (usually myself) so that I can create more accounts for customers.

UserManager<AppUser>.CreateAsync(AppUser user) is the right one to call because you don't want to put your password in the code/source control.

The user account created by the method above doesn't have the PasswordHash, like what others had mentioned. Hence you can't log in.

What I would do is to get to the application site, and click "Forgot password" (since I have that logic implemented as well). It would generate a password reset token, and send an email to my email with the link I can create to go back to the application to reset my password.

Comments

-5

I don't think you can validate user without password. As a workaround: Instead of blank password, I'll recommend to use some Dummy/Common password from C# code, both while creating User and while validating credential

When creating user

if (vm.ShouldHavePassword)
{
    userManager.Create(userToInsert, vm.Password);
}
else
{
    userManager.Create(userToInsert, "someDummy123$");
}

When validating

result = await SignInManager.PasswordSignInAsync(model.UserName, "someDummy123$", model.RememberMe, shouldLockout: false);

1 Comment

If anything you'd create a cryptographically random password and send the user a password reset email. But there is no scenario where you should use a dummy password that is the same for all users.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.