Let's say I have the following roles:
Admin
User
I want Admin role to impersonate specific user account with User role, but without knowing that specific user account's password.
Admin should be able to impersonate any user from the application and be able to browse the application as the user himself. I found a link where this is actually implemented in ASP.NET MVC 4.6, but having a little headaches while converting this to Core version.
Mostly because of the last line of code in the link
authenticationManager.SignIn(new AuthenticationProperties()
{ IsPersistent = false }, impersonatedIdentity);
where SignIn
parameter in .NET Core does not allow IdentityResult
class (impersonatedIdentity) to be passed anymore. It can now only take ClaimsPrincipal
.
So what I ended up doing was this,
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");
}
I populated necessary claims and passed it to ClaimsPrincipal
so SignInAsync
can now take var user
.
However, this seems like I am not actually logging in as the user found in AspNetUsers
table who has the role and privileges previously assigned by the Admin role. To be honest, I was expecting above code to at least sign-in as the Name and Surname I defined in var claims
, but in fact I am still logged-in as the admin account after I'm redirected to Index page.
What are the proper steps I need to take in order to sign-in as the user account defined in AspNetUsers
table so the Admin would be able to browse the application as the user himself?
In the application's Web. config file, set the impersonate attribute in the identity element to true. Set the NTFS access control list (ACL) for the ManagerInformation directory to allow access to only those identities that are in the Windows Manager group and any required system accounts.
web/identity@impersonate is set to true. Things you can try: If the application supports it, disable client impersonation. If you are certain that it is OK to ignore this error, it can be disabled by setting system. webServer/validation@validateIntegratedModeConfiguration to false.
Show activity on this post. var user = await _userManager. FindByIdAsync(UserId); var roles = await _userManager. GetRolesAsync(user); return OK(new { User = user, Roles = roles });
There is a blog post about impersonation in Asp.Net Core HERE. I am just searching for such a solution, so I have not tried implementing it yet. However it seems you are on the right track. There are only slight differences between your code and Max's.
Basically you need to replace the cookie at the browser side. So, for the next request the server "thinks" its someone else logged in. At least that's what I understood so far. This is why you better save the original identity in the cookie as well, thus you could switch back to the original user when needed.
I get back when I have a working solutions anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With