I'm implementing authentication and authorization for a simple web application built with ASP.NET Core 3.1. So far, ASP.NET Core Identity meets the requirements except for one: the default implementation of external logins (in this case, Google) does not seem to work with the default implementation of Two-Factor Authentication.
When I log in using a local account (with 2FA configured), I am prompted for the TOTP token. When I log in using a Google account, there is no prompt for the second factor. I have spend a few days researching this (e.g. learn.microsoft.com, Google, and here on SO) but found nothing useful. How can I get ASP.NET Core Identity to use Two-Factor Authentication for users who log in with Google?
Prerequisites:
Here's how I got it working.
OnGetCallbackAsync
method._signInManager.ExternalLoginSignInAsync()
and change the bypassTwoFactor
parameter from true to false.Find the conditional statements which check the result of ExternalLoginSignInAsync(), and add this code:
if (result.RequiresTwoFactor)
{
return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = false });
}
Putting it all together, you should have something like this:
// Sign in the user with this external login provider if the user already has a login.
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor : false);
if (result.Succeeded)
{
_logger.LogInformation("{Name} logged in with {LoginProvider} provider.", info.Principal.Identity.Name, info.LoginProvider);
return LocalRedirect(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = false });
}
if (result.IsLockedOut)
{
return RedirectToPage("./Lockout");
}
else
{
// existing code omitted for brevity
}
Note: Since I was unable to find any documentation or examples on how to do this, I accept that my implementation may not be optimal. If you know a better way, please share!