asp.net身份2外部登录不保存用户登录,登录提供商后无法找到用户

时间:2014-06-20 15:58:51

标签: asp.net identity

我在新的mvc项目中使用asp.net identity 2(我已将其设置为使用int用户id而不是默认字符串标识符)。它可以通过现有帐户成功登录,但如果我使用外部登录而不是使用与现有帐户相同的电子邮件,则使用Google登录,我可以使用Google登录并允许该应用,但是当它重定向时我对ExternalLoginCallback动作,它找不到用户。 GetExternalLoginInfoAsync()用于获取loginInfo,但当我将其传递给ExternalSignIn时,在其中,当它调用var user = await UserManager.FindAsync(loginInfo.Login);时无法找到用户。 FindAsync返回null。这可能是新身份框架中的错误吗?具有此电子邮件地址的用户已经存在于数据库中,因此它应该能够找到它(我已在其中验证过它)。

这是控制器动作(与asp.net身份示例项目中的动作完全相同):

    public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
    {
        var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
        if (loginInfo == null)
        {
            return RedirectToAction("Login");
        }

        // Sign in the user with this external login provider if the user already has a login
        var result = await SignInHelper.ExternalSignIn(loginInfo, isPersistent: false);
        switch (result)
        {
            case SignInStatus.Success:
                return RedirectToLocal(returnUrl);
            case SignInStatus.LockedOut:
                return View("Lockout");
            case SignInStatus.RequiresTwoFactorAuthentication:
                return RedirectToAction("SendCode", new { ReturnUrl = returnUrl });
            case SignInStatus.Failure:
            default:
                // If the user does not have an account, then prompt the user to create an account
                ViewBag.ReturnUrl = returnUrl;
                ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
                return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email });
        }
    }

以下是上述操作中调用的登录方法(也是身份示例项目中的内容):

    public async Task<SignInStatus> ExternalSignIn(ExternalLoginInfo loginInfo, bool isPersistent)
    {
        var user = await UserManager.FindAsync(loginInfo.Login);
        if (user == null)
        {
            return SignInStatus.Failure;
        }
        if (await UserManager.IsLockedOutAsync(user.Id))
        {
            return SignInStatus.LockedOut;
        }
        return await SignInOrTwoFactor(user, isPersistent);
    }

如果我将上述方法中的FindAsync更改为FindByEmailAsync,它会找到该用户 - 为什么不通过电子邮件找到该用户?即var user = await UserManager.FindByEmailAsync(loginInfo.Email);

刚做了一些研究,这似乎只有在你将pk更改为int并且必须创建一个新的自定义用户,角色等类时才会发生。

1 个答案:

答案 0 :(得分:0)

您正在尝试从新设置的标识对象中获取数据,但上下文尚未更新。

有两种解决方法:

- 等到上下文更新后,暂时不访问User.identity个信息,等待下一个电话。
- 尝试获取保存更新的上下文。

var store = new UserStore<ApplicationUser>(new MyDbContext());   
var manager = new UserManager(store);    
manager.UpdateAsync(user);   
var ctx = store.context;
ctx.saveChanges();
相关问题