[英]How do I use ASP.NET Identity 2.0 to allow a user to impersonate another user?
I'm migrating a ASP.NET MVC 5.1 application from MembershipProvider to ASP.NET Identity v2.0. 我正在将一个ASP.NET MVC 5.1应用程序从MembershipProvider迁移到ASP.NET Identity v2.0。 One of the features I have in the application is user impersonation: Administrators can be logged in as any other user registered on the site without knowing passwords.
我在应用程序中的一个功能是用户模拟:管理员可以在网站上注册的任何其他用户登录,而无需知道密码。
I used this code to implement user impersonation for the MembershipProvider and this does not work with Identity library. 我使用此代码实现MembershipProvider的用户模拟 ,这不适用于Identity库。
How do I implement user impersonation (not IIS impersonation) in ASP.NET Identity? 如何在ASP.NET标识中实现用户模拟(而不是IIS模拟)?
I've found a solution to this problem. 我找到了解决这个问题的方法。
Basically I add claim with admin username, if this claim exists, I know that impersonation is happening. 基本上我用admin用户名添加声明,如果这个声明存在,我知道假冒正在发生。 When admin wants to stop impersonation, system retrieves original username for the claims, deletes old impersonated-cookie and creates a new cookie for the admin:
当管理员想要停止模拟时,系统会检索声明的原始用户名,删除旧的模拟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);
}
More information is in my blog-post: User impersonation with ASP.Net Identity 2 . 更多信息在我的博客文章中: 用户模仿ASP.Net Identity 2 。
Upd July 2017: this topic is quite popular, so I've looked into user impersonation in Core and principles are very similar with updated API. 更新2017年7月:这个主题非常受欢迎,所以我研究了Core中的用户模仿,原理与更新的API非常相似。 Here is how to impersonate:
以下是如何冒充:
[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");
}
This is how to stop impersonation: 这是如何停止冒充:
[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");
}
Full explanation in my blog: http://tech.trailmax.info/2017/07/user-impersonation-in-asp-net-core/ Full code sample on GitHub: https://github.com/trailmax/AspNetCoreImpersonation 我的博客中有完整的解释: http : //tech.trailmax.info/2017/07/user-impersonation-in-asp-net-core/ GitHub上的完整代码示例: https : //github.com/trailmax/AspNetCoreImpersonation
Just for who is using the Asp Net Core Identity, this is the code to solve the initial problem (An Administrator that want to enter as user, without knowing password). 仅针对谁使用Asp Net Core Identity,这是解决初始问题的代码(管理员想要以用户身份输入,而不知道密码)。 The following solution is not a real "Impersonation" with token as in the voted answer :
以下解决方案不是带有令牌的真实“模拟”,如投票答案中所示:
[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");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.