将外部登录链接到现有用户

Ami*_*ila 8 asp.net-mvc oauth-2.0 asp.net-mvc-5 asp.net-identity-2

我是新手,Identity并试图通过观看https://channel9.msdn.com/Series/Customizing-ASPNET-Authentication-with-Identity中的视频来学习

在默认的ASP.Net MVC模板中,/Manage如果您已经登录,则可以将多个外部登录(google,facebook)链接到您的帐户(直通).

但是,如果用户首次使用他们的谷歌帐户登录我们的网站并从其注销,并在另一天尝试使用他们的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我更改了代码,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);
        }
Run Code Online (Sandbox Code Playgroud)

rob*_*ert 0

我对身份也相当陌生,并且遇到了同样的问题,尽管我的解决方案截然不同。我不使用实体框架,为了实现这一点,我必须使用自定义类基本上重写整个身份引擎。我有自己的 Sql Server 表,与 EF 创建的表不同。EF 将身份存储在 5 个表中:用户、角色、用户角色、用户声明和用户登录。我只用前三个。在我的环境中,不需要 AddLoginAsync,因为该表不存在。我将所有本地/外部登录和注册用户存储在用户表中。需要时,声明将存储为用户角色。

我解决重复用户名和电子邮件(使用具有相同注册电子邮件地址的不同提供商登录)的方法是在创建用户之前使用自定义 UserValidator 删除对现有用户名和电子邮件的验证检查。该表允许重复。登录时,我根据用户名/提供商(外部)或电子邮件/密码哈希(本地)进行唯一性自定义检查。似乎正在发挥作用。