Search code examples
c#asp.netasp.net-coreasp.net-identity

ASP .NET Core - sign in as other user / impersonate user and way back


As a member of an administrative role want to impersonate another user in my ASP .NET Core web application.

Basically I want to do this:

login as another user

I know that I can login as another user with:

await _signInManager.SignInAsync(appuser, false);

For a button "Go back to my own account" - how can I know that I'm currently impersonating another user and provide a "way back" to my own account.

Are there any built-in methods for this scenario?

go back to my account

Screenshots taken from ASP.NET Zero


Solution

  • I solved it with the following code.

    In AccountController:

        [Authorize(Roles="Administrators")]
        public async Task<IActionResult> ImpersonateUser(string id)
        {
            var appUser = await _userManager.FindByIdAsync(id);
            var userPrincipal = await _signInManager.CreateUserPrincipalAsync(appUser);
            userPrincipal.Identities.First().AddClaim(new Claim("OriginalUserId", User.FindFirst(x=>x.Type == ClaimTypes.NameIdentifier).Value));
    
            await _signInManager.SignOutAsync(); //sign out the current user
    
            //https://github.com/aspnet/Identity/blob/dev/src/Microsoft.AspNetCore.Identity/IdentityCookieOptions.cs
            await HttpContext.Authentication.SignInAsync("Identity.Application", userPrincipal); //impersonate the new user
    
            return RedirectToAction("Index", "Home");
        }
    
        public async Task<IActionResult> StopImpersonation()
        {
            var originalUserId = User.Claims.First(x => x.Type == "OriginalUserId").Value;
            var appUser = await _userManager.FindByIdAsync(originalUserId);
            await _signInManager.SignInAsync(appUser, false);
    
            return RedirectToAction("Index", "Home");
        }
    

    Basically this adds the claim OriginalUserId to the impersonated user. By checking if this claim exists I know I'm currently impersonating and can provide a way back to the original account using the code in StopImpersonation.

    The authentication scheme Identity.Application is the default.