如何使用ASP。NET Identity 2.0允许用户模拟其他用户?

时间:2022-12-03 22:51:50

I'm migrating a ASP.NET MVC 5.1 application from MembershipProvider to 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.

我迁移一个ASP。NET MVC 5.1从MembershipProvider到ASP的应用程序。净v2.0身份。我在应用程序中拥有的一个特性是用户模拟:管理员可以作为在不知道密码的情况下在站点上注册的其他用户登录。

I used this code to implement user impersonation for the MembershipProvider and this does not work with Identity library.

我使用此代码实现了MembershipProvider的用户模拟,这与标识库不兼容。

How do I implement user impersonation (not IIS impersonation) in ASP.NET Identity?

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

2 个解决方案

#1


49  

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. 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:

基本上,我用admin用户名添加了claim,如果这个claim存在,我知道正在发生模拟。当管理员想要停止模拟时,系统检索声明的原始用户名,删除旧的模拟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。净身份2。

User Impersonation in Asp.Net Core

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. Here is how to impersonate:

Upd 2017年7月:这个话题非常流行,所以我研究了用户模拟的核心和原则与更新后的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");
    }

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- asp-net-core/完整的代码样本在GitHub上:https://github.com/trailmax/aspnetcore。

#2


-1  

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). The following solution is not a real "Impersonation" with token as in the voted answer :

对于使用asp.net核心标识的用户来说,这是解决最初问题的代码(不知道密码的管理员希望以用户身份输入)。下面的解决方案并不是真正的“模拟”与标记,如投票的答案:

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

#1


49  

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. 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:

基本上,我用admin用户名添加了claim,如果这个claim存在,我知道正在发生模拟。当管理员想要停止模拟时,系统检索声明的原始用户名,删除旧的模拟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。净身份2。

User Impersonation in Asp.Net Core

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. Here is how to impersonate:

Upd 2017年7月:这个话题非常流行,所以我研究了用户模拟的核心和原则与更新后的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");
    }

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- asp-net-core/完整的代码样本在GitHub上:https://github.com/trailmax/aspnetcore。

#2


-1  

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). The following solution is not a real "Impersonation" with token as in the voted answer :

对于使用asp.net核心标识的用户来说,这是解决最初问题的代码(不知道密码的管理员希望以用户身份输入)。下面的解决方案并不是真正的“模拟”与标记,如投票的答案:

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