我对Identity
很新,并试图通过观看https://channel9.msdn.com/Series/Customizing-ASPNET-Authentication-with-Identity中的视频来学习
在默认的ASP.Net MVC模板中,如果您已经登录,则可以将多个外部登录(google,facebook)链接到您的帐户(通过/Manage
)。
但是,如果用户首次使用他们的Google帐户登录我们的网站并从该帐户退出并在另一天尝试使用他们的Facebook帐户登录,该怎么办?假设他们的facebook和Google帐户都使用相同的电子邮件地址,则用户将无法登录该网站,因为默认模板不允许,因为UserManager.CreateAsync
将失败。我知道他们可以更改他们的电子邮件和登录信息,但这会为同一个用户创建两个不同的帐户。
var info = await AuthenticationManager.GetExternalLoginInfoAsync();
if (info == null)
{
return View("ExternalLoginFailure");
}
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await UserManager.CreateAsync(user);
if (result.Succeeded)
{
result = await UserManager.AddLoginAsync(user.Id, info.Login);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
return RedirectToLocal(returnUrl);
}
}
我更改了ExternalLoginConfirmation
中的代码,以便检查用户是否存在并将新的外部提供商广告到AspNetUserLogins
。任何人都可以告诉我,如果这是正确的方法吗?或者如果有更好的方法。
if (ModelState.IsValid)
{
// Get the information about the user from the external login provider
var info = await AuthenticationManager.GetExternalLoginInfoAsync();
if (info == null)
{
return View("ExternalLoginFailure");
}
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await UserManager.CreateAsync(user);
if (result.Succeeded)
{
result = await UserManager.AddLoginAsync(user.Id, info.Login);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
return RedirectToLocal(returnUrl);
}
}
//new code begins
else if (UserManager.FindByEmail(model.Email) != null)
{
var usr = await UserManager.FindByEmailAsync(model.Email);
result = await UserManager.AddLoginAsync(usr.Id, info.Login);
if (result.Succeeded)
{
await SignInManager.SignInAsync(usr, isPersistent: false, rememberBrowser: false);
return RedirectToLocal(returnUrl);
}
}
//new code ends
AddErrors(result);
}
答案 0 :(得分:0)
我也很熟悉身份并遇到同样的问题,尽管我的解决方案完全不同。我不使用Entity Framework并实现这一点,我必须基本上用自定义类重写整个Identity引擎。我有自己的Sql Server表,它们与EF创建的表不同。 EF将身份存储在5个表中:用户,角色,用户角色,用户声明和用户登录。我只使用前三个。在我的环境中,不需要AddLoginAsync,因为该表不存在。我将所有本地/外部登录和注册用户存储在用户表中。声明在需要时存储为用户角色。
我绕过重复的UserNames和电子邮件(使用具有相同注册电子邮件地址的不同提供商登录)的方法是在创建用户之前使用自定义UserValidator删除现有用户名和电子邮件的验证检查。该表允许重复。登录时,我会根据用户名/提供商(外部)或电子邮件/密码哈希(本地)自定检查唯一性。它似乎正在发挥作用。