【问题标题】:ASP.NET Core 1.1 User Impersonation with IdentityASP.NET Core 1.1 用户模拟与身份
【发布时间】:2017-10-30 05:32:30
【问题描述】:

在尝试使用 .Net Core 的 Identity 实现用户模拟功能时遇到信息不足的问题。我试图让this ASP.NET MVC 4.6 code 在 ASP.NET Core 中工作,但遇到了一些 .NET Core 不再支持的代码行。

所以下面是原始的 4.6 代码,用于传入 userName 并以用户身份登录。

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);
}

我已经做到了,但坚持使用 context.GetOwinContext().Authentication 部分,我需要使用当前 cookie 退出,并使用这个新用户登录。

public async Task<IActionResult> ImpersonateUserAsync(string userName)
{
    var originalUsername = _httpContextAccessor.HttpContext.User.Identity.Name;

    var impersonatedUser = await _userManager.FindByNameAsync(userName);

    var impersonatedIdentity = await _userManager.CreateAsync(impersonatedUser);
    await _userManager.AddClaimAsync(impersonatedUser, new Claim("UserImpersonation", "true"));
    await _userManager.AddClaimAsync(impersonatedUser, new Claim("OriginalUsername", originalUsername));

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

有人用过这种方法吗?

【问题讨论】:

  • 您是否意识到_userManager.AddClaimAsync 正在将模拟声明添加到数据库中,而不仅仅是添加到cookie 中?因此,每次您使用此用户登录时,此假冒声明都会启用(除非您在取消假冒时将其从数据库中删除)
  • 这是一个很好的点 trailmax。正如您在链接中看到的那样,它们用于检测是否有人在进行模拟,并用于将用户取消模拟为管理员权限。当我取消模拟时,我应该删除它们。谢谢。
  • @trailmax 没有意识到是你在链接中写了关于模仿的文章。嗨,Trailmax。这当然是一个很好的方法。但是在 .Net Core 方面情况发生了变化。 SignIn 不再使用 var impersonatedIdentitySignIn 现在只能取ClaimsPrincipal。有什么想法吗?

标签: c# asp.net-identity impersonation asp.net-core-1.1 asp.net-core-identity


【解决方案1】:

使用HttpContext.Authentication

public async Task<IActionResult> ImpersonateUserAsync(string userName) {
    var context = HttpContext; //Property already exists in Controller

    var originalUsername = context.User.Identity.Name;

    var impersonatedUser = await _userManager.FindByNameAsync(userName);

    var impersonatedIdentity = await _userManager.CreateAsync(impersonatedUser);
    await _userManager.AddClaimAsync(impersonatedUser, new Claim("UserImpersonation", "true"));
    await _userManager.AddClaimAsync(impersonatedUser, new Claim("OriginalUsername", originalUsername));

    var authenticationManager = context.Authentication; 
    var cookie = DefaultAuthenticationTypes.ApplicationCookie;
    await authenticationManager.SignOutAsync(cookie);
    await authenticationManager.SignInAsync(cookie, impersonatedIdentity, 
        new AuthenticationProperties() { IsPersistent = false });

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

参考文档Using Cookie Middleware without ASP.NET Core Identity

【讨论】:

  • 谢谢 Nkosi,我猜HttpContext.Authentication 是要走的路,但SignInAsync 无法取impersonatedIdentity,参数只能取ClaimsPrincipal。你能解决这个问题吗?
  • 发现impersonatedIdentity是用来判断身份操作是否成功的。所以我不认为那行代码与SignInAsync 无关。所以我的观点是,SignInAsync 如何正确使用存储在AspNetUsers 表中的用户帐户登录(模拟)?
  • 创建一个声明原则并用必要的声明填充它,然后登录
  • 也许我可以创建一个声明列表var claimsnew Claim(ClaimTypes.Name, impersonatedUser.FirstName, ClaimValueTypes.String)new Claim(ClaimTypes.Email, impersonatedUser.Email, ClaimValueTypes.String) 并将它传递给ClaimsPrincipalvar user = new ClaimsPrincipal(new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme)); 但我相信它不是“实际上”登录为那个用户帐号?看起来它是在伪造它。我希望管理员以用户帐户的身份实际登录,以便管理员可以跨页面查看该用户分配的权限。
  • _userManager.CreateAsync 不创建新用户吗?然后AddClaimAsync 正在为该新用户存储声明?
猜你喜欢
  • 1970-01-01
  • 2022-11-17
  • 2011-12-11
  • 2021-06-23
  • 2022-10-05
  • 2019-03-25
  • 1970-01-01
  • 2015-09-13
  • 2012-02-25
相关资源
最近更新 更多