当UserLogin存在时,ExternalLoginSignInAsync返回失败响应

时间:2017-06-14 21:29:28

标签: c# entity-framework asp.net-identity identityserver4

我有一个用MVC,asp.net身份和IdentityServer4构建的asp.net核心网站。

我可以通过google登录注册流程,并浏览安全页面。但是,当我退出并尝试使用google功能登录时,用于调用var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);的ExternalLoginCallback代码会返回Failed响应,就好像我的aspnetUserLogin表中不存在该记录一样。

我已确认从info.LoginProvider传递的令牌,info.ProviderKey与我的userlogin表中的值匹配,因此我不确定为什么收到Failed响应。

注意我修改了标准外部注册码以创建具有emailconfirmed = true值的用户,但我仍然得到上述响应。

为什么当我在asp.net userlogin表中看到数据时,这个ExternalLoginSignInAsync方法返回失败了?

1 个答案:

答案 0 :(得分:0)

我会问一些问题,但尚无代表要发表评论。但是,我只是在努力并解决了这个问题(尽管造成您的具体原因可能有所不同),但我建议您采取以下步骤(对于遇到类似问题的任何人,而不仅仅是这篇文章):

确保在将UserLogin模型映射到表的DbContext类中,它看起来像这样:

modelBuilder.Entity<YourUserLogin>(entity => {
     entity.HasKey(e => new { e.LoginProvider, e.ProviderKey });
     ...
     }

这里的顺序很重要,因为FindByLoginAsync是如何定位UserLogin记录的。

然后,检查您的UserLogin和User类,并确保您要覆盖属性(假设您从Identity类继承):

public partial class YourUserLogin : IdentityUserLogin<string>

由于某种原因,当我通过EF架设数据库时,它没有覆盖这些字段;这将为每个字段创建一个副本,一个副本来自您的类,另一个来自继承的类;这会导致属性冲突,并且Identity会将这些值视为空。覆盖属性可以为我解决此问题。

通常,我建议(如果使用的是Visual Studio)在行var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);处放置一个断点,清除输出,然后按F10并分析输出;您将看到错误,或者看到类似EF生成脚本来寻找用户where UserId is null的信息(即,如果未找到UserLogin,您将看到此信息)。然后参考Identity github(因为它是开源的)并按照ExternalLoginSignInAsync采取的各个步骤进行操作;您最终会发现它失败的方法,这将极大地帮助您。

希望这会有所帮助。