c# - ASN.NET Core 2.0 Facebook 身份验证 ExternalLoginSignInAsync 失败(IsNotAllowed)

标签 c# asp.net-core asp.net-core-2.0 asp.net-core-identity

我正在使用 Ddentity 在 ASP.NET Core 2.0 中创建一个新应用程序。我已经根据 docs 启用了 Facebook 身份验证.

现在正在运行的流程如下:

  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 Controller 是项目的默认实现。

    [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 });
        }
    }

任何人都可以帮我找到我遗漏了什么或我应该看到什么才能得到答案吗?提前谢谢你。

最佳答案

IsNotAllowed 设置为 true 当您设置了 RequireConfirmedEmailRequireConfirmedPhoneNumberSignInOptions 上为 true (通常配置为 AddIdentity 的一部分)但电子邮件地址或电话号码尚未确认。

如果您不想要求外部登录的确认电子邮件或电话号码,您可以在创建您的 IdentityUser 派生类时设置相关属性。创建。例如:

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

否则,如果您确实希望验证过程发生,您可以按照 ASP.NET Core 中的指南进行操作 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;
}

关于c# - ASN.NET Core 2.0 Facebook 身份验证 ExternalLoginSignInAsync 失败(IsNotAllowed),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47268027/

相关文章:

c# - EF Core - 可能导致循环或多个级联路径

data-binding - Asp.net 核心 Razor 页面 [BindProperty] 不适用于集合

c# - 在响应 header 中传递非 ASCII 字符

c# - DataProtection - 在多个应用程序之间共享机器 key

c# - WP7图像处理API

c# - C# 中的选项卡式用户界面

c# - ConstructorInfo 可以没有 DeclaringType

c# - 为什么定义接口(interface)的方法和属性前面没有修饰符(public、private、protected)?

c# - ASP.NET Core - 无需等待即可发送电子邮件

javascript - 从 javascript 调用 Asp Action