UserManager.CheckPasswordAsync 与 SignInManager.PasswordSignInAsync

问题描述 投票:0回答:2

使用 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-core asp.net-core-identity
2个回答
65
投票

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

1. UserManager.CheckPasswordAsync

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

2. SignInManager.PasswordSignInAsync

这个方法还有很多作用。这是一个粗略的细分:

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

如果您对要求确认电子邮件、锁定等不感兴趣,那么使用

UserManager.CheckPasswordAsync
就足够了。


0
投票

我的简单看法是,我仍然需要使用 SignInManager.PasswordSignInAsync 来获得它提供的增强功能,但不希望它调用 IsTwoFactorClientRememberedAsync 因为它会创建一个身份验证 cookie(我的具体用例是将 ASP.NET Core Identity 包装在出于架构原因,REST API 外观)。

因此,我只是创建了一个派生自 SignInManager 的自定义类,并专门重写了

Task<SignInResult> CheckPasswordSignInAsync(TUser user, string password, bool lockoutOnFailure)
方法,使我能够有效地重新实现该方法,就像原始源中出现的那样 (https://github.com/dotnet /aspnetcore/blob/main/src/Identity/Core/src/SignInManager.cs),但没有调用 IsTwoFactorClientRememberedAsync。

似乎对我来说没问题。

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