代码之家  ›  专栏  ›  技术社区  ›  Anastasios Selmani

ASN。NET Core 2.0 Facebook验证ExternalLoginSignInAsync失败(不允许)

  •  3
  • Anastasios Selmani  · 技术社区  · 8 年前

    docs .

    当前正在运行的流程如下所示:

    1. 当新用户从facebook进行身份验证时,应用程序会要求发送电子邮件以用于应用程序
    2. 当用户提供电子邮件时,将在我的dbo中创建一个用户。AspNetUsers表中包含用户提供的电子邮件,并在我的dbo中创建了一行新行。AspNetUserLogins引用提供者、providerKey和userId。
    3. 在这一点上,我可以看到在我的数据库中,所有行都有正确的数据。

    现在,当用户注销并在某个时候尝试使用facebook再次登录时,应用程序会检查用户是否可以通过以下方式使用提供商凭据登录:

    // 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: true);
    

    这时,我的结果是NotAllowed(属性IsNotAllowed=true),它要求用户输入一封新的电子邮件(就像新用户的原始流一样)。当然,然后电子邮件已经注册,用户不能创建一个新帐户,因为他不应该这样做。

    我的ExternalLoginCallback控制器是项目的默认实现。

        [HttpGet]
        [AllowAnonymous]
        public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
        {
            if (remoteError != null)
            {
                ErrorMessage = $"Error from external provider: {remoteError}";
                return RedirectToAction(nameof(Login));
            }
            var info = await _signInManager.GetExternalLoginInfoAsync();
            if (info == null)
            {
                return RedirectToAction(nameof(Login));
            }
    
            // 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: true);
            if (result.Succeeded)
            {
                _logger.LogInformation("User logged in with {Name} provider.", info.LoginProvider);
                return RedirectToLocal(returnUrl);
            }
            if (result.IsLockedOut)
            {
                return RedirectToAction(nameof(Lockout));
            }
            else
            {
                // If the user does not have an account, then ask the user to create an account.
                ViewData["ReturnUrl"] = returnUrl;
                ViewData["LoginProvider"] = info.LoginProvider;
                var email = info.Principal.FindFirstValue(ClaimTypes.Email);
                return View("ExternalLogin", new ExternalLoginViewModel { Email = email });
            }
        }
    

    谁能帮我找到我遗漏了什么,或者我应该看到什么才能得到答案?提前谢谢你。

    1 回复  |  直到 8 年前
        1
  •  3
  •   Kirk Larkin    8 年前

    IsNotAllowed 设置为 true 当你设置了 RequireConfirmedEmail 或 RequireConfirmedPhoneNumber 真的 在…上 SignInOptions AddIdentity )但电子邮件地址或电话号码尚未确认。

    如果你不想 要求 确认的外部登录电子邮件或电话号码,您可以在创建 IdentityUser 第一次创建后的派生类。例如。:

    var identityUser = new IdentityUser
    {
        // ...
        EmailConfirmed = true,
        PhoneNumberConfirmed = true
    };
    

    否则,如果你 做 希望验证过程发生,您可以按照ASP。净核心 docs 对于电子邮件地址方面的事情。

    你可以看到这一切是如何在 source code . 你最后进了 PreSignInCheck :

    if (!await CanSignInAsync(user))
    {
        return SignInResult.NotAllowed;
    }
    

    这个 CanSignInAsync 实现如下(删除日志记录):

    public virtual async Task<bool> CanSignInAsync(TUser user)
    {
        if (Options.SignIn.RequireConfirmedEmail &&
            !(await UserManager.IsEmailConfirmedAsync(user)))
        {
            return false;
        }
    
        if (Options.SignIn.RequireConfirmedPhoneNumber &&
            !(await UserManager.IsPhoneNumberConfirmedAsync(user)))
        {
            return false;
        }
    
        return true;
    }