ASP.NET Core身份验证模块:模拟特定用户

7
假设我有以下角色:
  • 管理员
  • 用户
我想让管理员角色冒充拥有用户角色的特定用户帐户,但又不知道该特定用户帐户的密码。管理员应该能够在应用程序中模仿任何用户,并能够以用户自己的身份浏览应用程序。我找到了一个链接(http://tech.trailmax.info/2014/06/user-impersonation-with-asp-net-identity-2/),其中实际上在ASP.NET MVC 4.6中实现了这一点,但在将其转换为Core版本时遇到了一些麻烦。主要是由于链接中的最后一行代码。
authenticationManager.SignIn(new AuthenticationProperties() 
{ IsPersistent = false }, impersonatedIdentity);

在.NET Core中,SignIn参数不再允许传递IdentityResult类(模拟身份), 只能传递ClaimsPrincipal

所以我最终做的是这样的:

public async Task<IActionResult> ImpersonateUserAsync(string userName)
    { 
        var impersonatedUser = await _userManager.FindByNameAsync(userName);         

        var claims = new List<Claim> {
            new Claim(ClaimTypes.Name, impersonatedUser.FirstName, ClaimValueTypes.String),
            new Claim(ClaimTypes.Surname, impersonatedUser.LastName, ClaimValueTypes.String),
            new Claim(ClaimTypes.Email, impersonatedUser.Email, ClaimValueTypes.String)
        };

        var user = new ClaimsPrincipal(new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme));

        var authenticationManager = _httpContextAccessor.HttpContext.Authentication;
        await authenticationManager.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        await authenticationManager.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user, new AuthenticationProperties() { IsPersistent = false });

        return RedirectToAction("Index", "Home");
    }

我添加了必要的声明并将其传递给ClaimsPrincipal,这样SignInAsync现在可以接受var user。 然而,这似乎并没有像我预期的那样以AspNetUsers表中找到的用户身份登录,该用户已经被分配了管理员角色和权限。说实话,我原以为上述代码至少会作为我在var claims中定义的名称和姓氏进行登录,但事实上,在重定向到Index页面后,我仍然以管理员帐户登录。

为了能够作为在AspNetUsers表中定义的用户帐户登录,我需要采取哪些正确的步骤,使管理员能够以用户本身的身份浏览应用程序?


首先,非常小心地实现这种功能,因为它可能会让你面临法律责任,特别是如果你处理信用卡信息或健康信息。其次,你需要提供一些审计功能,以表明用户被冒名顶替了,这样可以证明是否是真正的用户还是被冒名顶替的用户做了某些事情。 - Erik Funkenbusch
谢谢您的建议,但我们已经与客户达成了协议,所以不用担心。这里有什么解决问题的想法/方法吗? - bbusdriver
1
你尝试过这里的解决方案吗:https://dev59.com/tGAf5IYBdhLWcg3w52E_#42059249 - 请注意,它使用的是SigninManager而不是AuthenticationManager。 - Erik Funkenbusch
谢谢,我会看一下的。 - bbusdriver
1个回答

12

有一篇关于Asp.Net Core模拟登录的博客文章链接在这里。我正在寻找这样的解决方案,所以我还没有尝试实现它。但是看起来你已经在正确的方向上了,你的代码和Max的之间只有轻微的差别。

基本上,你需要在浏览器端替换cookie。因此,对于下一次请求,服务器会“认为”另一个用户已登录。至少这是我到目前为止所理解的。这就是为什么最好将原始身份也保存在cookie中,以便在需要时可以切换回原始用户。

无论如何,当我有可行的解决方案时,我会回来的。


它进行得如何?可以解释一下博客链接吗? - Chaim Eliyah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接