具有外部登录的 MVC 5 身份的 userLogins 始终为 0
MVC 5 Identity with external login has userLogins always 0
我有一个带有外部登录的 MVC 5 站点 运行 身份。我只是稍微修改了一下,将 f/l 姓名和用户名与电子邮件分开。
我没有注册新用户,我只是通过 Fackbook 登录...(这可能是问题所在?)
如果我通过 Facebook 登录,它会在身份 tables 中创建一个用户(但不会创建密码哈希)。
然而,当我导航到 'Manage' 控制器时,它显示
External Logins: 0 [ Manage ]
当我点击 'manage'
时,它会将我带到 'Manage/ManageLogins' 并显示一个 Facebook 按钮...但是在点击 FB 按钮后,我得到 'an error has occurred'
查看 Manage Controller,我发现此方法受到攻击,但它收集 userLogins 的地方却没有。
// GET: /Manage/ManageLogins
public async Task<ActionResult> ManageLogins(ManageMessageId? message)
{
ViewBag.StatusMessage =
message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
: message == ManageMessageId.Error ? "An error has occurred."
: "";
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user == null)
{
return View("Error");
}
--> var userLogins = await UserManager.GetLoginsAsync(User.Identity.GetUserId()); <-- here it doesn't get any
var otherLogins = AuthenticationManager.GetExternalAuthenticationTypes().Where(auth => userLogins.All(ul => auth.AuthenticationType != ul.LoginProvider)).ToList();
ViewBag.ShowRemoveButton = user.PasswordHash != null || userLogins.Count > 1;
return View(new ManageLoginsViewModel
{
CurrentLogins = userLogins,
OtherLogins = otherLogins
});
}
注意:UserManager.GetLoginsAsync
总是返回 0 并且我已经验证 User.Identity.GetUserId()
正在返回用户的 ID...它只是没有得到用户。我刚刚用一个新创建的本地用户尝试了这个。
此代码仅在存在 userLogin 时显示 'remove' 按钮...但通过外部登录登录时未创建 userLogin。
这是正常的吗?我期待创建一个 userLogin 并引用到外部,但我不确定身份如何处理这方面...
我该如何解决这个问题,以便我的用户仍然可以取消关联他们的 FB 帐户?还是因为它是外部登录并且从未真正注册为本地帐户,所以没有真正的帐户可以取消关联?...这就是我所缺少的吗?这是预期的行为吗?
PS:我必须在 AccountContoller 的 ExternalLogin
方法中的 ChallengeResult
调用之前添加一行代码来终止任何现有会话:
// POST: /Account/ExternalLogin
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
here--> ControllerContext.HttpContext.Session.RemoveAll();
// Request a redirect to the external login provider
return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
}
这会导致任何问题吗?必须用这一行开箱即用地修复 Identity 似乎很奇怪..(虽然它被谈论了很多)
编辑:
我注意到在 'IdentityUserLogins' table 中,它显示了 'Facebook' 的 LoginProvider 并且 userId 是我的用户..但是,ApplicationUserId 字段为空.. 在放置 userid 时进入此字段后,'remove' 按钮会显示在管理页面中....
我错过了什么?
为什么没有输入 applicationUserID?..默认身份的另一个修复?
Found the answer here
我已将我的身份模型移动到与 Web 项目分开的 'Data' 项目中。这个 post 中的人也有类似的问题,他的 Id 也为空。对 fluent-api 和 voila.
稍作改动
var user = modelBuilder.Entity<TUser>()
.ToTable("AspNetUsers");
user.HasMany(u => u.Roles).WithRequired().HasForeignKey(ur => ur.UserId);
user.HasMany(u => u.Claims).WithRequired().HasForeignKey(uc => uc.UserId);
user.HasMany(u => u.Logins).WithRequired().HasForeignKey(ul => ul.UserId);
user.Property(u => u.UserName).IsRequired();
modelBuilder.Entity<TUserRole>()
.HasKey(r => new { r.UserId, r.RoleId })
.ToTable("AspNetUserRoles");
modelBuilder.Entity<TUserLogin>()
.HasKey(l => new { l.UserId, l.LoginProvider, l.ProviderKey})
.ToTable("AspNetUserLogins");
modelBuilder.Entity<TUserClaim>()
.ToTable("AspNetUserClaims");
var role = modelBuilder.Entity<TRole>()
.ToTable("AspNetRoles");
role.Property(r => r.Name).IsRequired();
role.HasMany(r => r.Users).WithRequired().HasForeignKey(ur => ur.RoleId);
我敢于进行如下更改并且效果很好:
//modelBuilder.Entity<IdentityUser>().ToTable("Usuario", "dbo");
var user = modelBuilder.Entity<IdentityUser>()
.ToTable("Usuario", "dbo");
user.HasMany(u => u.Logins).WithRequired().HasForeignKey(ul => ul.UserId);
我有一个带有外部登录的 MVC 5 站点 运行 身份。我只是稍微修改了一下,将 f/l 姓名和用户名与电子邮件分开。
我没有注册新用户,我只是通过 Fackbook 登录...(这可能是问题所在?) 如果我通过 Facebook 登录,它会在身份 tables 中创建一个用户(但不会创建密码哈希)。
然而,当我导航到 'Manage' 控制器时,它显示
External Logins: 0 [ Manage ]
当我点击 'manage'
时,它会将我带到 'Manage/ManageLogins' 并显示一个 Facebook 按钮...但是在点击 FB 按钮后,我得到 'an error has occurred'
查看 Manage Controller,我发现此方法受到攻击,但它收集 userLogins 的地方却没有。
// GET: /Manage/ManageLogins
public async Task<ActionResult> ManageLogins(ManageMessageId? message)
{
ViewBag.StatusMessage =
message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
: message == ManageMessageId.Error ? "An error has occurred."
: "";
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user == null)
{
return View("Error");
}
--> var userLogins = await UserManager.GetLoginsAsync(User.Identity.GetUserId()); <-- here it doesn't get any
var otherLogins = AuthenticationManager.GetExternalAuthenticationTypes().Where(auth => userLogins.All(ul => auth.AuthenticationType != ul.LoginProvider)).ToList();
ViewBag.ShowRemoveButton = user.PasswordHash != null || userLogins.Count > 1;
return View(new ManageLoginsViewModel
{
CurrentLogins = userLogins,
OtherLogins = otherLogins
});
}
注意:UserManager.GetLoginsAsync
总是返回 0 并且我已经验证 User.Identity.GetUserId()
正在返回用户的 ID...它只是没有得到用户。我刚刚用一个新创建的本地用户尝试了这个。
此代码仅在存在 userLogin 时显示 'remove' 按钮...但通过外部登录登录时未创建 userLogin。 这是正常的吗?我期待创建一个 userLogin 并引用到外部,但我不确定身份如何处理这方面...
我该如何解决这个问题,以便我的用户仍然可以取消关联他们的 FB 帐户?还是因为它是外部登录并且从未真正注册为本地帐户,所以没有真正的帐户可以取消关联?...这就是我所缺少的吗?这是预期的行为吗?
PS:我必须在 AccountContoller 的 ExternalLogin
方法中的 ChallengeResult
调用之前添加一行代码来终止任何现有会话:
// POST: /Account/ExternalLogin
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
here--> ControllerContext.HttpContext.Session.RemoveAll();
// Request a redirect to the external login provider
return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
}
这会导致任何问题吗?必须用这一行开箱即用地修复 Identity 似乎很奇怪..(虽然它被谈论了很多)
编辑: 我注意到在 'IdentityUserLogins' table 中,它显示了 'Facebook' 的 LoginProvider 并且 userId 是我的用户..但是,ApplicationUserId 字段为空.. 在放置 userid 时进入此字段后,'remove' 按钮会显示在管理页面中.... 我错过了什么? 为什么没有输入 applicationUserID?..默认身份的另一个修复?
Found the answer here
我已将我的身份模型移动到与 Web 项目分开的 'Data' 项目中。这个 post 中的人也有类似的问题,他的 Id 也为空。对 fluent-api 和 voila.
稍作改动var user = modelBuilder.Entity<TUser>()
.ToTable("AspNetUsers");
user.HasMany(u => u.Roles).WithRequired().HasForeignKey(ur => ur.UserId);
user.HasMany(u => u.Claims).WithRequired().HasForeignKey(uc => uc.UserId);
user.HasMany(u => u.Logins).WithRequired().HasForeignKey(ul => ul.UserId);
user.Property(u => u.UserName).IsRequired();
modelBuilder.Entity<TUserRole>()
.HasKey(r => new { r.UserId, r.RoleId })
.ToTable("AspNetUserRoles");
modelBuilder.Entity<TUserLogin>()
.HasKey(l => new { l.UserId, l.LoginProvider, l.ProviderKey})
.ToTable("AspNetUserLogins");
modelBuilder.Entity<TUserClaim>()
.ToTable("AspNetUserClaims");
var role = modelBuilder.Entity<TRole>()
.ToTable("AspNetRoles");
role.Property(r => r.Name).IsRequired();
role.HasMany(r => r.Users).WithRequired().HasForeignKey(ur => ur.RoleId);
我敢于进行如下更改并且效果很好:
//modelBuilder.Entity<IdentityUser>().ToTable("Usuario", "dbo");
var user = modelBuilder.Entity<IdentityUser>()
.ToTable("Usuario", "dbo");
user.HasMany(u => u.Logins).WithRequired().HasForeignKey(ul => ul.UserId);