Asp.Net核心身份,更新现有的纯文本密码

问题描述 投票:1回答:1

我们已经定制了Asp.Net Core来使用我们的学生表而不是AspNetUser表。一切都适合新生。但我们需要更新现有学生的密码。当学生登录或者这可以一次性完成时,我想做这样的事情(在AccountController Login方法中)...

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    if (ModelState.IsValid)
    {
        // Require the user to have a confirmed email before they can log on.
        var user = await _userManager.FindByEmailAsync(model.Email);
        if (user != null)
        {
            if (user.PasswordHash == null)
            {
                user.EmailConfirmed = true;
                user.UserName = model.Email;
                user.NormalizedEmail = model.Email.ToUpper();
                user.NormalizedUserName = user.NormalizedEmail;
                //user.PasswordHash = ?;
                //user.SecurityStamp = ?;
                //update user in database.
            }
            //continue on with login process
        }
    }
}

下面的代码(来自Register方法)创建一个新用户并将他添加到数据库中。这不是我们想要的。

var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
    // …
c# asp.net-core passwords asp.net-identity
1个回答
2
投票

你会发现UserManager有你需要设置用户密码的任何东西。虽然您可以直接使用内部密码hasher,但通过用户管理器可确保用户实体在密码方面正确更新。所以你可以依靠用户经理“做正确的事”。

如果用户没有密码,您可以使用AddPasswordAsync进行设置:

var user = await _userManager.FindByEmailAsync(model.Email);
if (user != null && !(await _userManager.HasPasswordAsync(user)))
{
    // retrieve plaintext password
    var originalPassword = GetPlainTextPassword(user);

    var result = await _userManager.AddPasswordAsync(user, originalPassword);

    if (!result.Succeeded)
    {
        // handle error
    }
}

否则,您还可以使用密码重置流并生成令牌,然后立即使用该令牌重置用户的密码(实际上不涉及用户)。所以你基本上链接GeneratePasswordResetTokenAsyncResetPasswordAsync。当然,这只应该出于维护原因:

var user = await _userManager.FindByEmailAsync(model.Email);
if (user != null)
{
    // retrieve plaintext password
    var originalPassword = GetPlainTextPassword(user);

    // retrieve token
    var resetToken = await _userManager.GeneratePasswordResetTokenAsync(user);

    // reset password
    var result = await _userManager.ResetPasswordAsync(user, resetToken, originalPassword);

    if (!result.Succeeded)
    {
        // handle error
    }
}

无论如何,我仍然建议您主动要求用户自己重置密码。只需从数据库中删除纯文本密码,并保留空密码。这样,用户将不得不首先重置密码(您应该添加一个说明,说明他们必须在首次登录之前执行此操作),并且没有人能够以纯文本格式看到他们的新密码。 - 旧密码在数据库中公开,并且可能(希望?!)大量备份,即使您认为您的系统是安全的,也可能并不完美。并且仍然有人可以访问数据库并且可以直接或间接地将这些密码暴露给其他人(有或没有好意)。你不应该相信你的系统足以让一切都不会出错。用户不应该信任您保持密码安全。你应该告诉他们制作一个新密码并摆脱他们的旧密码 - 比以后更好。

© www.soinside.com 2019 - 2024. All rights reserved.