如何使用ASP ?NET Identity 2.0允许用户冒充另一个用户

本文关键字:用户 许用户 另一个 冒充 ASP 何使用 NET Identity | 更新日期: 2023-09-27 18:08:02

我正在迁移一个ASP。从MembershipProvider到asp.net MVC 5.1应用程序。. NET Identity v2.0。我在应用程序中的一个特性是用户模拟:管理员可以像在站点上注册的任何其他用户一样登录,而无需知道密码。

我使用这段代码来实现MembershipProvider的用户模拟,但这不适用于Identity库。

如何在ASP中实现用户模拟(不是IIS模拟)?净身份?

如何使用ASP ?NET Identity 2.0允许用户冒充另一个用户

我找到了一个解决这个问题的方法。

基本上我用admin用户名添加声明,如果这个声明存在,我知道正在发生冒充。当admin想要停止冒充时,系统为声明检索原始用户名,删除旧的冒充cookie并为admin创建一个新的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);
}

更多的信息是在我的博客帖子:用户模拟与ASP。2.网络身份

Asp中的用户模拟。网络核心h1> 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

对于正在使用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");
    }