ASN.NET Core 2.0 Facebook身份validationExternalLoginSignInAsync失败(IsNotAllowed)

我正在使用Ddentity在ASP.NET Core 2.0中创建一个新的应用程序。 我根据文档启用了Facebook身份validation。

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

  1. 当新用户从Facebook进行身份validation时,应用程序会要求发送电子邮件以便用于该应用程序
  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 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 }); } } 

任何人都可以帮我找到我错过的或者我应该看到什么才能得到答案? 提前谢谢你。

当您在RequireConfirmedEmailRequireConfirmedPhoneNumber设置为true (通常配置为AddIdentity一部分)但未确认电子邮件地址或电话号码时, IsNotAllowed设置为true

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

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

否则,如果您确实希望进行validation过程,则可以按照ASP.NET核心文档中的指南查看电子邮件地址方面的内容。

您可以在源代码中看到这一切是如何工作的。 你最终进入了PreSignInCheck

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

CanSignInAsync实现如下所示(删除了日志记录):

 public virtual async Task 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; }