ASP.NET 零和外部认证

ASP.NET Zero and external authentication

我们将用 Node.js 编写的旧 Web 应用程序迁移到 ASP.NET 零。我们必须保留所有用户及其密码,以便他们仍然能够登录。使用 bcrypt 对密码进行哈希处理。

计划如下:当用户在迁移后首次登录时,我们授权 him/her 反对 brypt 密码,如果密码有效,我们使用 _userManager.PasswordHasher.HashPassword(user, plainPassword) 并将其保存为 his/her 密码。下次该用户想要登录时,将调用标准 ASP.NET 零函数来实现此目的。

第一部分 - bcrypt 工作得很好,但我不知道如何使用标准机制来验证用户。这是我目前所拥有的:

private readonly IRepository<User, long> _userRepository;
private readonly SignInManager<User> _signInManager;
private readonly UserManager _userManager;

public AltAuthSource(IRepository<User, long> userRepository, UserManager userManager, SignInManager<User> signInManager)
{
    _userRepository = userRepository;
    _userManager = userManager;
    _signInManager = signInManager;
}

public override Task<bool> TryAuthenticateAsync(string userNameOrEmailAddress, string plainPassword, Tenant tenant)
{
    var user = _userRepository.GetAll().FirstOrDefault(x => x.UserName.Equals(userNameOrEmailAddress, StringComparison.InvariantCultureIgnoreCase) || x.EmailAddress.Equals(userNameOrEmailAddress, StringComparison.InvariantCultureIgnoreCase));

    if (user == null)
    {
        return Task.FromResult(false);
    }
    else
    {
        if (string.IsNullOrWhiteSpace(user.Password))
        {
            var passwordOk = BCrypt.Net.BCrypt.Verify(plainPassword, user.PasswordOrig);

            if (passwordOk)
            {
                _userManager.ResetAccessFailedCountAsync(user);

                var newHash = _userManager.PasswordHasher.HashPassword(user, plainPassword);
                user.Password = newHash;

                return Task.FromResult(true);
            }
            else
            {
                _userManager.AccessFailedAsync(user);
                return Task.FromResult(false);
            }
        }
        else
        {
            var passwordOk = _signInManager.PasswordSignInAsync(user, plainPassword, false, false);

            if (passwordOk.Result.Succeeded)
            {
                _userManager.ResetAccessFailedCountAsync(user);
                return Task.FromResult(true);
            }
            else
            {
                _userManager.AccessFailedAsync(user);
                return Task.FromResult(false);
            }
        }
    }
}

如果有人已经解决了这个问题,你能指出正确的方向吗?

在深入研究 Abp 源代码后,我发现如果用户未被外部源验证,Abp 仍会尝试对其数据库进行身份验证。所以这很可能解决了我的问题:

public class AltAuthSource: DefaultExternalAuthenticationSource<Tenant, User>, ITransientDependency
{
    private readonly IRepository<User, long> _userRepository;
    private readonly UserManager _userManager;

    public override string Name => "AltSource";

    public AltAuthSource(IRepository<User, long> userRepository, UserManager userManager)
    {
        _userRepository = userRepository;
        _userManager = userManager;
    }

    public override Task<bool> TryAuthenticateAsync(string userNameOrEmailAddress, string plainPassword, Tenant tenant)
    {
        var user = _userRepository.GetAll().FirstOrDefault(x => x.UserName.Equals(userNameOrEmailAddress, StringComparison.InvariantCultureIgnoreCase) || x.EmailAddress.Equals(userNameOrEmailAddress, StringComparison.InvariantCultureIgnoreCase));

        if (user == null || !string.IsNullOrWhiteSpace(user.Password))
        {
            return Task.FromResult(false);
        }
        else
        {
            var passwordOk = BCrypt.Net.BCrypt.Verify(plainPassword, user.PasswordOrig);

            if (passwordOk)
            {
                _userManager.ResetAccessFailedCountAsync(user);

                var newHash = _userManager.PasswordHasher.HashPassword(user, plainPassword);
                user.Password = newHash;

                return Task.FromResult(true);
            }
            else
            {
                _userManager.AccessFailedAsync(user);
                return Task.FromResult(false);
            }
        }
    }
}

还是我忽略了什么?