Asp.NET Core Identity Two Factor Authentication with Authenticator App Issue in Azure Environment

1.8k Views Asked by At

I have implemented the Two Factor Authentication using Asp.NET Identity Framework. I have used the authenticator app mode. Everything works fine in localhost environment but when I deployed it to Azure the final step of Two Factor login part is not working.

Following are the highlights of the code.

Here is how I generate the QR Code Uri.

 private async Task<QRCodeDto> GetTwoFactorSetupDataAsync(User user)
        {
            var operationResult = new QRCodeDto();
            var key = await _userManager.GetAuthenticatorKeyAsync(user); // get the key
            if (string.IsNullOrEmpty(key))
            {
                // if no key exists, generate one and persist it
                await _userManager.ResetAuthenticatorKeyAsync(user);

                // get the key we just created
                key = await _userManager.GetAuthenticatorKeyAsync(user);
            }

            operationResult.Uri = GenerateQrCodeUri(user.Email, key);
            operationResult.Key = key;
            operationResult.UserId = user.Id;
            return operationResult;
        }

  private string GenerateQrCodeUri(string email, string unformattedKey)
        {
            const string AuthenticatorUriFormat = "otpauth://totp/{0}:{1}?secret={2}&issuer={0}&digits=6";

            return string.Format(
                AuthenticatorUriFormat,
                HttpUtility.UrlEncode("ABC Company Name"),
                HttpUtility.UrlEncode(email),
                unformattedKey);
        }

Here is how I verify the authenticator.

 public async Task<VerifiedAuthenticatorResultDto> VerifyAuthenticator(VerifyAuthenticatorDto verifyAuthenticator)
        {
            var operationResult = new VerifiedAuthenticatorResultDto();
            var verificationCode = verifyAuthenticator.VerificationCode.Replace(" ", string.Empty).Replace("-", string.Empty);
            var user = await _userManager.FindByIdAsync(verifyAuthenticator.UserId.ToString());
            if (user != null)
            {
                var is2FaTokenValid = await _userManager.VerifyTwoFactorTokenAsync(
                user, _userManager.Options.Tokens.AuthenticatorTokenProvider, verificationCode);
                if (!is2FaTokenValid)
                {
                    operationResult.IsSuccess = false;
                    operationResult.Message = "Invalid verification code.";
                    return operationResult;
                }

                operationResult.IsSuccess = true;
                operationResult.Message = "Your authenticator app has been verified";

                if (await _userManager.CountRecoveryCodesAsync(user) != 0)
                {
                    return operationResult;
                }
                else
                {
                    operationResult.RecoveryCodes = await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 5);
                    return operationResult;
                }
            }

            operationResult.IsSuccess = false;
            operationResult.Message = "Error verifying authenticator app.";
            return operationResult;
        }

Up to here it works fine and generates the verification codes as well. But from the following code _signInManager.TwoFactorAuthenticatorSignInAsync() and _signInManager.TwoFactorRecoveryCodeSignInAsync() always fails. Only works in local environment. But not in Azure.

public async Task<TwoFactorSignInResult> TwoFactorLogin(TwoFactorLoginInfo loginInfo)
        {
            var signInResult = new TwoFactorSignInResult();
            UserDto loginUserDto = null;
            SignInResult result = null;

            // Require the user to have a confirmed email before they can log on.
            var user = await _userManager.FindByNameAsync(loginInfo.UserName);
            if (user == null)
            {
                throw new InvalidUserException("Invalid Username.");
            }

            var authenticatorCode = loginInfo.TwoFactorCode.Replace(" ", string.Empty).Replace("-", string.Empty);

            if (!loginInfo.UseRecoveryCode)
            {
                result = await _signInManager.TwoFactorAuthenticatorSignInAsync(authenticatorCode, true,
                    loginInfo.RememberMachine);
            }
            else
            {
                result = await _signInManager.TwoFactorRecoveryCodeSignInAsync(authenticatorCode);
            }

            if (result.Succeeded)
            {
               
                signInResult.IsSuccess = true;
                signInResult.Message = "Successfully Logged in.";
                return signInResult;
            }
            else
            {
                throw new InvalidUserException("Invalid token.");
            }
        }

    

I have referred this article. Is there any configuration that I have to do in Azure in order for this to work?

0

There are 0 best solutions below