是什么导致SignInManager.SendTwoFactorCodeAsync返回false?

时间:2016-07-11 16:04:01

标签: asp.net asp.net-mvc owin

有关新Microsoft Identity Framework的文档似乎有点稀疏。我目前正在修改标准项目模板,在尝试使用双因素身份验证登录用户时,我遇到了一些奇怪的行为。

我们仅通过短信允许2FA,因此我绕过了用户选择他们想要的代码的选项。相反,当具有2FA和验证电话号码的用户尝试登录时,他们会触发此代码:

var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: true);
switch (result)
{
    case SignInStatus.RequiresVerification:
        if (!await SignInManager.SendTwoFactorCodeAsync("Phone Code"))
        {
            TempData["ErrorMessage"] = "We could not verify your account. Please try again.";
            return RedirectToAction("Error", "Error");
        }
        return RedirectToAction("VerifyCode", new { Provider = "Phone Code", ReturnUrl = returnUrl, RememberMe = model.RememberMe });
    // other cases
}

大部分时间,这都很好。但是,在用户注销后,他们第一次重新登录时,SendTwoFactorCodeAsync会返回false,并且会将其定向到错误页面。

哪些情况会导致SendTwoFactorCodeAsync在第一次为已注销的用户调用时始终失败?

2 个答案:

答案 0 :(得分:3)

我忘了Owin的O代表Open。源代码可以回答这个问题:

public virtual async Task<bool> SendTwoFactorCodeAsync(string provider)
{
    var userId = await GetVerifiedUserIdAsync().WithCurrentCulture();
    if (userId == null)
    {
        return false;
    }

    var token = await UserManager.GenerateTwoFactorTokenAsync(userId, provider).WithCurrentCulture();
    // See IdentityConfig.cs to plug in Email/SMS services to actually send the code
    await UserManager.NotifyTwoFactorTokenAsync(userId, provider, token).WithCurrentCulture();
    return true;
}

这来自SignInManager,因此调用GetVerifiedUserIdAsync()与从您的应用程序调用{​​{1}}相同。

答案 1 :(得分:0)

只需将此vb代码转换为C#。我太懒了,但是你明白了。

   Dim result = Await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout := False)
   Select Case result
     Case SignInStatus.RequiresVerification    
         Dim xUser = UserManager.FindByEmail(model.Email)
         Dim TwoFA_code = UserManager.GenerateTwoFactorToken(xUser.Id.ToString, "Email Code")
         Dim TwoFA_Result = UserManager.NotifyTwoFactorToken(xUser.Id.ToString, "Email Code", TwoFA_code)

         Return RedirectToAction("VerifyCode", New With {
                    returnUrl,
                    model.RememberMe
                })

    End Select