Is there a way to add a master password which could be used to login into user accounts created using .NET Identities. I would like an easy way for our system administrator to login to someone's account so they can see exactly what the customer would see when logged in.
One way would be to change the
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
method, so that it checks that the supplied password is indeed the master one, and if so use the supplied email address to grab the user, and then login normally with:
await SignInManager.SignInAsync(user, true, model.RememberMe);
Does this seem OK? Is there a better way?
There's an actual word for this: Impersonation.
Here's a link that will show you how to implement it.
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);
}
Extension method to detect impersonation:
public static bool IsImpersonating(this IPrincipal principal)
{
if (principal == null)
{
return false;
}
var claimsPrincipal = principal as ClaimsPrincipal;
if (claimsPrincipal == null)
{
return false;
}
return claimsPrincipal.HasClaim("UserImpersonation", "true");
}
Use the previous code like this:
if(HttpContext.Current.User.IsImpersonating())
{
// do my stuff for admins
}
And revert back.
public async Task RevertImpersonationAsync()
{
var context = HttpContext.Current;
if (!HttpContext.Current.User.IsImpersonating())
{
throw new Exception("Unable to remove impersonation because there is no impersonation");
}
var originalUsername = HttpContext.Current.User.GetOriginalUsername();
var originalUser = await userManager.FindByNameAsync(originalUsername);
var impersonatedIdentity = await userManager.CreateIdentityAsync(originalUser, DefaultAuthenticationTypes.ApplicationCookie);
var authenticationManager = context.GetOwinContext().Authentication;
authenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = false }, impersonatedIdentity);
}