简体   繁体   English

ASP .NET Core 标识 - Microsoft.AspNetCore.Identity.SignInManager:警告:用户未能提供正确的密码

[英]ASP .NET Core Identity - Microsoft.AspNetCore.Identity.SignInManager: Warning: User failed to provide the correct password

I have an existing .NET 4.x database with Identity running.我有一个运行 Identity 的现有 .NET 4.x 数据库。 I am able to login just fine with it.我可以用它登录就好了。 I am upgrading my application to .NET Core with Identity.我正在将我的应用程序升级到带有标识的 .NET Core。 I've been through a bunch of issues.我经历了一堆问题。 I'm doing to getting the error message in identity:我正在做以身份获取错误消息:

Microsoft.AspNetCore.Identity.UserManager: Warning: Invalid password for user. Microsoft.AspNetCore.Identity.UserManager:警告:用户密码无效。 Microsoft.AspNetCore.Identity.SignInManager: Warning: User failed to provide the correct password. Microsoft.AspNetCore.Identity.SignInManager:警告:用户未能提供正确的密码。

The code that I am using is:我正在使用的代码是:

var findUser = await signinManager.PasswordSignInAsync(userName, Password, false, false);

-- or -- var au = new AspNetUser() { UserName = userName, EmailConfirmed = true }; -- 或 -- var au = new AspNetUser() { UserName = userName, EmailConfirmed = true }; var res = await _userManager.CheckPasswordAsync(au, Password); var res = await _userManager.CheckPasswordAsync(au, Password);

The exact error I get depends on whether or not I try to sign in via the UserManager or the SignInManager .我得到的确切错误取决于我是否尝试通过UserManagerSignInManager

I have set the following in the Startup.cs file:我在Startup.cs文件中设置了以下内容:

    services.AddIdentity<AspNetUser, AspNetRole>().AddEntityFrameworkStores<GolfGameContext>();
    services.Configure<IdentityOptions>(options =>
    {
        options.SignIn.RequireConfirmedAccount = false;
        options.SignIn.RequireConfirmedEmail = false;
        options.SignIn.RequireConfirmedPhoneNumber = false;
    });
    services.Configure<PasswordHasherOptions>(options => options.CompatibilityMode = PasswordHasherCompatibilityMode.IdentityV2);

I would think that the changing of the setting for the password hashing algo would allow my existing userid/password combo to connect to the database.我认为更改密码散列算法的设置将允许我现有的用户 ID/密码组合连接到数据库。

I have updated my db schema.我已经更新了我的数据库架构。 I have set the NormalizedEmail and NormalizedUserName to the uppercase version of the email and the username.我已将NormalizedEmailNormalizedUserName设置为电子邮件和用户名的大写版本。 I have also directly set the confirmed phone number and the confirmed email values to true in the database.我还直接在数据库中将确认的电话号码和确认的电子邮件值设置为 true。

Any ideas on how to correctly connect are appreciated.任何有关如何正确连接的想法都值得赞赏。

Perhaps the issue is that: Asp.net Identity and Asp.net Core Identity uses the different hashing algorithm to generate the Hash Password.也许问题在于:Asp.net Identity 和 Asp.net Core Identity 使用不同的散列算法来生成散列密码。 Even you have changed the set the Asp.net core PasswordHasherOptions to V2 version, the generate hash password is still not same with the Asp.net Identity generated hash password.即使您将 Asp.net core PasswordHasherOptions 的设置更改为 V2 版本,生成的哈希密码仍然与 Asp.net Identity 生成的哈希密码不同。

For the Asp.net Identity, it uses the following code to hash the Password (refer the source code ):对于 Asp.net Identity,它使用以下代码来散列密码(请参阅源代码):

    private const int PBKDF2IterCount = 1000; // default for Rfc2898DeriveBytes
    private const int PBKDF2SubkeyLength = 256/8; // 256 bits
    private const int SaltSize = 128/8; // 128 bits

    /* =======================
     * HASHED PASSWORD FORMATS
     * =======================
     * 
     * Version 0:
     * PBKDF2 with HMAC-SHA1, 128-bit salt, 256-bit subkey, 1000 iterations.
     * (See also: SDL crypto guidelines v5.1, Part III)
     * Format: { 0x00, salt, subkey }
     */

    public static string HashPassword(string password)
    {
        if (password == null)
        {
            throw new ArgumentNullException("password");
        }

        // Produce a version 0 (see comment above) text hash.
        byte[] salt;
        byte[] subkey;
        using (var deriveBytes = new Rfc2898DeriveBytes(password, SaltSize, PBKDF2IterCount))
        {
            salt = deriveBytes.Salt;
            subkey = deriveBytes.GetBytes(PBKDF2SubkeyLength);
        }

        var outputBytes = new byte[1 + SaltSize + PBKDF2SubkeyLength];
        Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize);
        Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, PBKDF2SubkeyLength);
        return Convert.ToBase64String(outputBytes);
    }

In the Asp.net Core Identity, it will use the PasswordHasher to hash the password (refer the source code ):在 Asp.net Core Identity 中,它将使用 PasswordHasher 来散列密码(请参阅源代码):

    public virtual string HashPassword(TUser user, string password)
    {
        if (password == null)
        {
            throw new ArgumentNullException(nameof(password));
        }

        if (_compatibilityMode == PasswordHasherCompatibilityMode.IdentityV2)
        {
            return Convert.ToBase64String(HashPasswordV2(password, _rng));
        }
        else
        {
            return Convert.ToBase64String(HashPasswordV3(password, _rng));
        }
    }

    private static byte[] HashPasswordV2(string password, RandomNumberGenerator rng)
    {
        const KeyDerivationPrf Pbkdf2Prf = KeyDerivationPrf.HMACSHA1; // default for Rfc2898DeriveBytes
        const int Pbkdf2IterCount = 1000; // default for Rfc2898DeriveBytes
        const int Pbkdf2SubkeyLength = 256 / 8; // 256 bits
        const int SaltSize = 128 / 8; // 128 bits

        // Produce a version 2 (see comment above) text hash.
        byte[] salt = new byte[SaltSize];
        rng.GetBytes(salt);
        byte[] subkey = KeyDerivation.Pbkdf2(password, salt, Pbkdf2Prf, Pbkdf2IterCount, Pbkdf2SubkeyLength);

        var outputBytes = new byte[1 + SaltSize + Pbkdf2SubkeyLength];
        outputBytes[0] = 0x00; // format marker
        Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize);
        Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, Pbkdf2SubkeyLength);
        return outputBytes;
    }

To solve this issue, since the existing user password is hashed using Asp.net Identity.为了解决这个问题,因为现有的用户密码是使用 Asp.net Identity 散列的。 When you login, you could query the database and get the HashedPassword based on the user name, and then use the Asp.net Identity VerifyHashedPassword method to verify the HashedPassword.登录时,可以查询数据库,根据用户名获取HashedPassword,然后使用Asp.net Identity VerifyHashedPassword方法验证HashedPassword。 Code as below:代码如下:

    public async Task<IActionResult> OnPostAsync(string returnUrl = null)
    {
        returnUrl = returnUrl ?? Url.Content("~/");

        if (ModelState.IsValid)
        {

            // This doesn't count login failures towards account lockout
            // To enable password failures to trigger account lockout, set lockoutOnFailure: true
            //var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);

            //get the hashedpassword from the database.
            var hashedpassword = _dbContext.Users.Where(c => c.UserName == Input.Email).FirstOrDefault().PasswordHash;

            var result = VerifyHashedPassword(hashedpassword, Input.Password);

           //if success, reditect to returnUrl, else show error message.

Asp.net Identity VerifyHashedPassword method: Asp.net Identity VerifyHashedPassword 方法:

    private const int PBKDF2IterCount = 1000; // default for Rfc2898DeriveBytes
    private const int PBKDF2SubkeyLength = 256 / 8; // 256 bits
    private const int SaltSize = 128 / 8; // 128 bits

    // hashedPassword must be of the format of HashWithPassword (salt + Hash(salt+input)
    public static bool VerifyHashedPassword(string hashedPassword, string password)
    {
        if (hashedPassword == null)
        {
            return false;
        }
        if (password == null)
        {
            throw new ArgumentNullException("password");
        }

        var hashedPasswordBytes = Convert.FromBase64String(hashedPassword);

        // Verify a version 0 (see comment above) text hash.

        if (hashedPasswordBytes.Length != (1 + SaltSize + PBKDF2SubkeyLength) || hashedPasswordBytes[0] != 0x00)
        {
            // Wrong length or version header.
            return false;
        }

        var salt = new byte[SaltSize];
        Buffer.BlockCopy(hashedPasswordBytes, 1, salt, 0, SaltSize);
        var storedSubkey = new byte[PBKDF2SubkeyLength];
        Buffer.BlockCopy(hashedPasswordBytes, 1 + SaltSize, storedSubkey, 0, PBKDF2SubkeyLength);

        byte[] generatedSubkey;
        using (var deriveBytes = new Rfc2898DeriveBytes(password, salt, PBKDF2IterCount))
        {
            generatedSubkey = deriveBytes.GetBytes(PBKDF2SubkeyLength);
        }
        return ByteArraysEqual(storedSubkey, generatedSubkey);
    }

    // Compares two byte arrays for equality. The method is specifically written so that the loop is not optimized.
    [MethodImpl(MethodImplOptions.NoOptimization)]
    private static bool ByteArraysEqual(byte[] a, byte[] b)
    {
        if (ReferenceEquals(a, b))
        {
            return true;
        }

        if (a == null || b == null || a.Length != b.Length)
        {
            return false;
        }

        var areSame = true;
        for (var i = 0; i < a.Length; i++)
        {
            areSame &= (a[i] == b[i]);
        }
        return areSame;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 尝试激活“xxxxx.LoginModel”时无法解析“Microsoft.AspNetCore.Identity.SignInManager”类型的服务 - Unable to resolve service for type 'Microsoft.AspNetCore.Identity.SignInManager` while attempting to activate 'xxxxx.LoginModel' ASP .NET Core 标识登录管理器 - ASP .NET Core Identity SignInManager 在 Asp.Net Core 3 Identity 中创建自定义 SignInManager - Creating a custom SignInManager in Asp.Net Core 3 Identity ASP.NET Core 2.0标识:SignInManager.IsSignedIn(User)在登录后返回false - ASP.NET Core 2.0 Identity: SignInManager.IsSignedIn(User) returns false after signing in 在ASP.net核心身份(UserManager和SignInManager)是否可以立即禁止用户? - In ASP.net core Identity (UserManager & SignInManager) is it possible to ban a user immediately? Microsoft.AspNetCore.Identity.UserManager:警告:用户验证失败:InvalidUserName;InvalidEmail - Microsoft.AspNetCore.Identity.UserManager:Warning: User validation failed: InvalidUserName;InvalidEmail Microsoft.AspNetCore.Identity.UserManager:警告:VerifyUserTokenAsync() 失败,目的是:ResetPassword for user - Microsoft.AspNetCore.Identity.UserManager: Warning: VerifyUserTokenAsync() failed with purpose: ResetPassword for user ASP.NET 核心 3:无法从根提供商解析范围服务“Microsoft.AspNetCore.Identity.UserManager`1[Alpha.Models.Identity.User]” - ASP.NET Core 3: Cannot resolve scoped service 'Microsoft.AspNetCore.Identity.UserManager`1[Alpha.Models.Identity.User]' from root provider VS 2017 ASP.NET Core测试项目-缺少Microsoft.AspNetCore.Identity - VS 2017 ASP.NET Core Test Project - Microsoft.AspNetCore.Identity missing Asp.Net Core没有类型为Microsoft.AspNetCore.Identity.RoleManager的服务 - Asp.Net Core No Service for Type Microsoft.AspNetCore.Identity.RoleManager
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM