C# 如何使用ASP.NET Identity 2.0允许用户模拟其他用户?
我正在将ASP.NET MVC 5.1应用程序从MembershipProvider迁移到ASP.NET Identity v2.0。我在应用程序中拥有的一个功能是用户模拟:管理员可以作为在站点上注册的任何其他用户登录,而不需要知道密码 我使用此代码创建了一个标识库,但它不适用于标识库C# 如何使用ASP.NET Identity 2.0允许用户模拟其他用户?,c#,asp.net-mvc,asp.net-identity,C#,Asp.net Mvc,Asp.net Identity,我正在将ASP.NET MVC 5.1应用程序从MembershipProvider迁移到ASP.NET Identity v2.0。我在应用程序中拥有的一个功能是用户模拟:管理员可以作为在站点上注册的任何其他用户登录,而不需要知道密码 我使用此代码创建了一个标识库,但它不适用于标识库 如何在ASP.NET Identity中实现用户模拟(而不是IIS模拟)?我找到了解决此问题的方法 基本上我用管理员用户名添加声明,如果这个声明存在,我知道模拟正在发生。当管理员想要停止模拟时,系统检索声明的原始
如何在ASP.NET Identity中实现用户模拟(而不是IIS模拟)?我找到了解决此问题的方法 基本上我用管理员用户名添加声明,如果这个声明存在,我知道模拟正在发生。当管理员想要停止模拟时,系统检索声明的原始用户名,删除旧的模拟cookie并为管理员创建新cookie:
[AuthenticateAdmin] // <- make sure this endpoint is only available to admins
public async Task ImpersonateUserAsync(string userName)
{
var context = HttpContext.Current;
var originalUsername = context.User.Identity.Name;
var impersonatedUser = await userManager.FindByNameAsync(userName);
var impersonatedIdentity = await userManager.CreateIdentityAsync(impersonatedUser, DefaultAuthenticationTypes.ApplicationCookie);
impersonatedIdentity.AddClaim(new Claim("UserImpersonation", "true"));
impersonatedIdentity.AddClaim(new Claim("OriginalUsername", originalUsername));
var authenticationManager = context.GetOwinContext().Authentication;
authenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = false }, impersonatedIdentity);
}
[AuthenticateAdmin]/仅针对使用Asp Net Core身份的用户,这是解决初始问题的代码(希望以用户身份输入而不知道密码的管理员)。以下解决方案不是投票答案中带有令牌的真实“模拟”:
[Authorize("Administrator")]
public async Task<IActionResult> ImpersonateUserAsync(string email)
{
var impersonatedUser = await _userManager.FindByNameAsync(email); //Usually username is the email
await _signInManager.SignOutAsync(); //signout admin
await _signInManager.SignInAsync(impersonatedUser,false); //Impersonate User
return RedirectToAction("Index","Home");
}
[授权(“管理员”)]
公共异步任务模拟同步(字符串电子邮件)
{
var impersonatedUser=await _userManager.FindByNameAsync(email);//通常用户名是电子邮件
等待_signInManager.SignOutAsync();//注销管理员
wait _signInManager.SignInAsync(模拟用户,false);//模拟用户
返回重定向到操作(“索引”、“主页”);
}
寻找非现场资源的问题是离题的。我对你的问题进行了编辑,以获得与主题相关的答案,但它仍然达到了相同的目的。@GeorgeStocker感谢的工作。似乎SecurityStampValidator
的实现已经更新为具有区域性,因此创建该类的修改版本要复杂一些,因为它有内部依赖项,现在也需要对其进行抄袭(It TBH的不可扩展性让人惊讶)。很简单。工作非常好。@spender你是说它已经在v3中更新了吗?我看到对v2分支的上一次更新是在2015年4月,在nuget packageMicrosoft.AspNet.Identity.Owin
2.2.1版中,有几个调用从SecurityStampValidator
到扩展方法Microsoft.AspNet.Identity.TaskExtensions.WithCurrentCulture
。因为TaskExtensions
类是internal
(即在我的程序集中不可见),这意味着我也必须复制它才能让它工作。@spender-huh。。我想我不知怎么错过了。。。或者被忽略。你是一个账本管理员。这不是模拟,只是作为另一个用户登录。对于真正的模拟,您需要以原始用户身份登录。好的,David,这是真的。但是Trailamx的第一个问题是:“管理员可以像任何其他用户一样在不知道密码的情况下登录到该站点”。使用上面的方法,例如,通过使用Asp.Net标识[Authorize(“Administrator”)],您解决了Asp.Net核心中的原始问题。请注意,Authorize语句中的“Administrator”必须是在Asp.Net Identity System表中配置的角色。是的,这仍然是一个小问题,这是我真正的问题。一旦您完成了作为模拟用户所需的任何操作,您也将被迫以管理员身份重新登录。这就是为什么这种方法对我来说不是特别可行的原因。@Giuliofronterota在Core中看到我关于模拟的更新答案
[Authorize(Roles = "Admin")] // <-- Make sure only admins can access this
public async Task<IActionResult> StopImpersonation()
{
if (!User.IsImpersonating())
{
throw new Exception("You are not impersonating now. Can't stop impersonation");
}
var originalUserId = User.FindFirst("OriginalUserId").Value;
var originalUser = await _userManager.FindByIdAsync(originalUserId);
await _signInManager.SignOutAsync();
await _signInManager.SignInAsync(originalUser, isPersistent: true);
return RedirectToAction("Index", "Home");
}
[Authorize("Administrator")]
public async Task<IActionResult> ImpersonateUserAsync(string email)
{
var impersonatedUser = await _userManager.FindByNameAsync(email); //Usually username is the email
await _signInManager.SignOutAsync(); //signout admin
await _signInManager.SignInAsync(impersonatedUser,false); //Impersonate User
return RedirectToAction("Index","Home");
}