首页 > 解决方案 > UserManager.CheckPasswordAsync 与 SignInManager.PasswordSignInAsync

问题描述

使用 asp net core 身份 - 当用户提供密码和用户名以获取 jwt 令牌时,他们将凭据发布到 /api/token

我的令牌控制器方法应该使用 usermanager 使用 CheckPasswordAsync 检查密码,如果通过返回令牌,还是应该使用 signinmanager 并调用 PasswordSignInAsync,然后根据该结果返回令牌?

我看过这两种方法的例子,想知道每种方法有什么好处,一种方法比另一种更好吗?

目前我的团队中有人写了以下内容:

[AllowAnonymous]
[HttpPost]
public async Task<ActionResult<User>> Post([FromBody]User model)
{
    try
    {                                              
        var user = await _userManager.FindByNameAsync(model.Username);
        if (user == null)
            return StatusCode(StatusCodes.Status401Unauthorized, "Incorrect username or password");

        var passwordOK = await _userManager.CheckPasswordAsync(user, model.Password);
        if (!passwordOK)
            return StatusCode(StatusCodes.Status401Unauthorized, "Incorrect username or password");

        model.Id = user.Id;
        model.Name = user.DisplayName;
        model.Password = "";               

        int expiresIn;
        long expiresOn;
        model.Token = _authorisationService.GetJWTToken(model.Username, user.Id, out expiresIn, out expiresOn);
        model.ExpiresIn = expiresIn;
        model.ExpiresOn = expiresOn;

        return model;
    }
    catch (Exception)
    {
        // log the exception
        return StatusCode(StatusCodes.Status500InternalServerError);
    }
}

但我认为有些事情是不必要的。

标签: c#asp.net-coreasp.net-core-identity

解决方案


您提到的两种方法有不同的用途:

1. UserManager.CheckPasswordAsync

此方法对提供的密码进行哈希处理,并将其与现有密码哈希(例如,存储在数据库中)进行比较。

2.SignInManager.PasswordSignInAsync

这种方法做得更多。这是一个粗略的细分:

  • 检查是否允许登录。例如,如果用户在被允许登录之前必须拥有确认的电子邮件,则该方法返回SignInResult.Failed.
  • 调用UserManager.CheckPasswordAsync以检查密码是否正确(如上所述)。
    • 如果密码不正确且支持锁定,则该方法会跟踪失败的登录尝试。如果超过了配置的登录尝试失败次数,该方法将用户锁定在外。
  • 如果为用户启用了双因素身份验证,则该方法会设置相关的 cookie 并返回SignInResult.TwoFactorRequired.
  • ClaimsPrincipal最后,执行登录过程,最终通过 cookie创建并保存它。

如果您对要求确认电子邮件、锁定等不感兴趣,那么UserManager.CheckPasswordAsync在您的问题中使用 as 就足够了。


推荐阅读