SignInManager 在 TwoFactorAuthenticatorSignInAsync() 和 TwoFactorSignInAsync() 中始终失败。

huangapple go评论129阅读模式
英文:

SignInManager always fails for TwoFactorAuthenticatorSignInAsync() and TwoFactorSignInAsync()

问题

背景

我正在使用.NET 6构建一个API,在其中尝试实现使用Google Authenticator的双因素身份验证。一切都运行正常,直到我尝试使用认证器应用程序提供的代码进行登录的最后步骤。

代码

双因素身份验证设置 - 第一部分:

  1. [HttpGet("TwoFactorAuthSetup/{email}")]
  2. public async Task<IActionResult> GetTwoFactorAuthSetup(string email)
  3. {
  4. ...
  5. var isTwoFactorAuthEnabled = await _userManager.GetTwoFactorEnabledAsync(user);
  6. var authenticatorKey = await _userManager.GetAuthenticatorKeyAsync(user);
  7. if (authenticatorKey == null)
  8. {
  9. await _userManager.ResetAuthenticatorKeyAsync(user);
  10. authenticatorKey = await _userManager.GetAuthenticatorKeyAsync(user);
  11. }
  12. ...
  13. }

双因素身份验证设置 - 第二部分:

  1. [HttpPost("TwoFactorAuthSetup")]
  2. public async Task<IActionResult> SetupTwoFactorAuth([FromBody] TwoFactorAuthSetupDto model)
  3. {
  4. var user = await _userManager.FindByEmailAsync(model.Email);
  5. var isCodeValid = await _userManager
  6. .VerifyTwoFactorTokenAsync(user,
  7. _userManager.Options.Tokens.AuthenticatorTokenProvider,
  8. model.Code);
  9. if (!isCodeValid)
  10. {
  11. return BadRequest("Invalid code");
  12. }
  13. await _userManager.SetTwoFactorEnabledAsync(user, true);
  14. ...
  15. }

双因素身份验证登录:

  1. [HttpPost("login-2fa")]
  2. [AllowAnonymous]
  3. public async Task<IActionResult> LoginWithTwoFactorAuth(TwoFactorAuthSetupDto model)
  4. {
  5. var user = await _userManager.FindByEmailAsync(model.Email);
  6. if (user == null)
  7. {
  8. return Unauthorized();
  9. }
  10. var result = await _signInManager.TwoFactorSignInAsync(_userManager.Options.Tokens.AuthenticatorTokenProvider, model.Code, true, false);
  11. var result2 = await _signInManager.TwoFactorAuthenticatorSignInAsync(model.Code, true, false);
  12. }

双因素身份验证设置的第一部分和第二部分按预期运行;我能够在我的应用程序中成功设置authenticatorKey,并且控制器能够接受6位代码。

问题出现在尝试使用认证器应用程序登录时。无论是result还是result2最终都为Succeeded = false。当我尝试使用_userManager.VerifyTwoFactorTokenAsync方法时,它确实显示我使用的代码是有效的。我不确定该如何继续。

英文:

Background

I'm building an API with .NET 6 where I'm currently trying to implement two factor authentication using Google Authenticator. It seems to be working fine up until the final part where I actually try to sign in using the code provided by the authenticator app.

Code

2FA Setup - Part 1:

  1. [HttpGet("TwoFactorAuthSetup/{email}")]
  2. public async Task<IActionResult> GetTwoFactorAuthSetup(string email)
  3. {
  4. ...
  5. var isTwoFactorAuthEnabled = await _userManager.GetTwoFactorEnabledAsync(user);
  6. var authenticatorKey = await _userManager.GetAuthenticatorKeyAsync(user);
  7. //var authenticatorKey = await _userManager.GenerateNewAuthenticatorKey(user);
  8. if (authenticatorKey == null)
  9. {
  10. await _userManager.ResetAuthenticatorKeyAsync(user);
  11. authenticatorKey = await _userManager.GetAuthenticatorKeyAsync(user);
  12. }
  13. ...

2FA Setup - Part 2:

  1. [HttpPost("TwoFactorAuthSetup")]
  2. public async Task<IActionResult> SetupTwoFactorAuth([FromBody] TwoFactorAuthSetupDto model)
  3. {
  4. var user = await _userManager.FindByEmailAsync(model.Email);
  5. var isCodeValid = await _userManager
  6. .VerifyTwoFactorTokenAsync(user,
  7. _userManager.Options.Tokens.AuthenticatorTokenProvider,
  8. model.Code);
  9. if (!isCodeValid)
  10. {
  11. return BadRequest("Invalid code");
  12. }
  13. await _userManager.SetTwoFactorEnabledAsync(user, true);
  14. ...

2FA Login:

  1. [HttpPost("login-2fa")]
  2. [AllowAnonymous]
  3. public async Task<IActionResult> LoginWithTwoFactorAuth(TwoFactorAuthSetupDto model)
  4. {
  5. var user = await _userManager.FindByEmailAsync(model.Email);
  6. //user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
  7. if (user == null)
  8. {
  9. return Unauthorized();
  10. }
  11. //var isValid = await _userManager.VerifyTwoFactorTokenAsync(user, _userManager.Options.Tokens.AuthenticatorTokenProvider, model.Code);
  12. var result = await _signInManager.TwoFactorSignInAsync(_userManager.Options.Tokens.AuthenticatorTokenProvider, model.Code, true, false);
  13. var result2 = await _signInManager.TwoFactorAuthenticatorSignInAsync( model.Code, true, false);

Both 2FA Setup - Part 1 and 2FA Setup - Part 2 work as expected; I'm able to successfully setup the authenticatorKey in my app, and the 6-digit code gets accepted by my controller.

The issue arises when trying to sign in using the authenticator app. Both result and result2 always end up with Succeeded = false. When I try to use the _userManager.VerifyTwoFactorTokenAsync method instead, it does show me that the code I use is valid. I'm unsure of how to proceed.

答案1

得分: 1

我弄清楚了。如果你有类似的问题,请考虑以下两个步骤:

  • 使用 _signInManager.PasswordSignInAsync 登录用户。这会生成一个 cookie,以便在用户选择记住我时记住用户。

  • 使用 var user = _signInManager.GetTwoFactorAuthenticationUserAsync() 来检查 Identity.TwoFactorUserId cookie 的存在。

我之前犯了一些错误:

  • 我使用了 _signInManager.CheckPasswordSignInAsync 而不是 _signInManager.PasswordSignInAsync
  • 我错误地使用了 var user = await _userManager.FindByEmailAsync(model.Email); 来获取需要执行两因素身份验证登录的用户。这存在安全风险。我后来用 await _signInManager.GetTwoFactorAuthenticationUserAsync() 替换了这一行。

通过上述更改,现在它按预期工作。

英文:

I figured it out. In case you have a similar issue, consider the following two steps -

  • Use _signInManager.PasswordSignInAsync to sign in the user. This drops a cookie that helps remember the user in case they had ticked the remember me.

  • Use var user = _signInManager.GetTwoFactorAuthenticationuserAsync() which checks for the presence of the Identity.TwoFactorUserId cookie.

I made few mistakes earlier:

  • I used _signInManager.CheckPasswordSignInAsync instead of _signInManager.PasswordSignInAsync.
  • I mistakenly used var user = await _userManager.FindByEmailAsync(model.Email); to get the user for which 2 factor auth login had to be performed. This provides a security risk. I since replaced this line with await _signInManager.GetTwoFactorAuthenticationUserAsync().

With the changes mentioned above it now works as intended.

huangapple
  • 本文由 发表于 2023年5月21日 06:01:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76297515.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定