我正在将一个ASP.NET MVC 5.1应用程序从MembershipProvider迁移到ASP.NET Identity v2.0。我在应用程序中的一个功能是用户模仿:管理员可以在网站上注册的任何其他用户登录,而无需知道密码。
我将此代码用于implement user impersonation for the MembershipProvider,但这不适用于Identity库。
如何在ASP.NET Identity中实现用户模拟(而不是IIS模拟)?
答案 0 :(得分:55)
我找到了解决这个问题的方法。
基本上我使用管理员用户名添加声明,如果此声明存在,我知道假冒正在发生。当管理员想要停止模拟时,系统会检索声明的原始用户名,删除旧的模拟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);
}
更多信息在我的博文中:User impersonation with ASP.Net Identity 2。
2017年7月更新:这个主题非常受欢迎,因此我研究了Core中的用户模拟,原则与更新的API非常相似。以下是如何冒充:
[Authorize(Roles = "Admin")] // <-- Make sure only admins can access this
public async Task<IActionResult> ImpersonateUser(String userId)
{
var currentUserId = User.GetUserId();
var impersonatedUser = await _userManager.FindByIdAsync(userId);
var userPrincipal = await _signInManager.CreateUserPrincipalAsync(impersonatedUser);
userPrincipal.Identities.First().AddClaim(new Claim("OriginalUserId", currentUserId));
userPrincipal.Identities.First().AddClaim(new Claim("IsImpersonating", "true"));
// sign out the current user
await _signInManager.SignOutAsync();
// If you use asp.net core 1.0
await HttpContext.Authentication.SignInAsync(cookieOptions.ApplicationCookieAuthenticationScheme, userPrincipal);
// If you use asp.net core 2.0 (the line above is deprecated)
await HttpContext.SignInAsync(cookieOptions.ApplicationCookieAuthenticationScheme, userPrincipal);
return RedirectToAction("Index", "Home");
}
这是如何停止冒充:
[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");
}
我博客中的完整说明:http://tech.trailmax.info/2017/07/user-impersonation-in-asp-net-core/ GitHub上的完整代码示例:https://github.com/trailmax/AspNetCoreImpersonation
答案 1 :(得分:-1)
仅针对谁使用Asp Net Core Identity,这是解决初始问题的代码(管理员想要以用户身份输入,而不知道密码)。以下解决方案不是带有令牌的真实“模拟”,如投票答案所示:
[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");
}