Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with method VerifyTwoFactorTokenAsync() in net core identity 2.1

I'm using .Net Core Identity 2.1 to enable authenticator with qrcode. When I use method VerifyTwoFactorTokenAsync() and run in localhost, it works fine. But when I upload to host, it doesn't work and is2faTokenValid always return false. Has anyone had a similar issue and found a solution or knows where I'm making a mistake?

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> EnableAuthenticator(AuthenticatorModel model)
        {
            var user = await GetCurrentUserAsync();
            if (user == null)
            {
                return NotFound($"Not found user with Id '{_userManager.GetUserId(User)}'.");
            }

            if (!ModelState.IsValid)
            {
                await LoadSharedKeyAndQrCodeUriAsync(user);
                return View();
            }

            // Strip spaces and hypens
            var verificationCode = model.Code.Replace(" ", string.Empty).Replace("-", string.Empty);
            var is2faTokenValid = await _userManager.VerifyTwoFactorTokenAsync(
                user, _userManager.Options.Tokens.AuthenticatorTokenProvider, verificationCode);  
            if (!is2faTokenValid)
            {

                ModelState.AddModelError("", "Invalid code.");
                var newmodel = await LoadSharedKeyAndQrCodeUriAsync(user);
                return View(newmodel);
            }

            await _userManager.SetTwoFactorEnabledAsync(user, true);
            var userId = await _userManager.GetUserIdAsync(user);
            _logger.LogInformation("User with ID '{UserId}' has enabled 2FA with an authenticator app.", userId);
            return Redirect("/Account/TwoFactorAuthentication");
        }
        private Task<AppUser> GetCurrentUserAsync()
        {
            return _userManager.GetUserAsync(User);
        }
        private async Task<AuthenticatorModel> LoadSharedKeyAndQrCodeUriAsync(AppUser user)
        {
            // Load the authenticator key & QR code URI to display on the form
            var unformattedKey = await _userManager.GetAuthenticatorKeyAsync(user);
            if (string.IsNullOrEmpty(unformattedKey))
            {
                await _userManager.ResetAuthenticatorKeyAsync(user);
                unformattedKey = await _userManager.GetAuthenticatorKeyAsync(user);
            }            
            var model = new AuthenticatorModel();
            model.SharedKey = FormatKey(unformattedKey);
            var userName = await _userManager.GetUserNameAsync(user);
            model.AuthenticatorUri = GenerateQrCodeUri(userName, unformattedKey);
            return model;
        }
like image 430
Hiếu Nguyễn Avatar asked Mar 20 '26 08:03

Hiếu Nguyễn


1 Answers

Xem thời gian máy chủ và thời gian của thiết bị có cái nào sai sai ko:

TOTP client and server time skew

TOTP (Time-based One-Time Password) authentication depends on both the server and authenticator device having an accurate time. Tokens only last for 30 seconds. If TOTP 2FA logins are failing, check that the server time is accurate, and preferably synchronized to an accurate NTP service.

use: sync with an internet time server: time.nist.gov dont use: time.windows.com

like image 104
NamPT Avatar answered Mar 21 '26 21:03

NamPT