我有一个用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
方法返回失败了?
答案 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
采取的各个步骤进行操作;您最终会发现它失败的方法,这将极大地帮助您。
希望这会有所帮助。