有没有办法为使用 C#.NET Identities 创建的用户帐户创建主密码?

Is there a way to create a master password for user accounts created using C#.NET Identities?

有没有办法添加一个主密码,该密码可用于登录到使用 .NET Identities 创建的用户帐户。我希望我们的系统管理员可以通过一种简单的方式登录某人的帐户,这样他们就可以准确地看到客户在登录时会看到什么。

一种方法是更改​​

public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)

方法,以便它检查提供的密码确实是主密码,如果是,则使用提供的电子邮件地址获取用户,然后正常登录:

await SignInManager.SignInAsync(user, true, model.RememberMe);

这样可以吗?有没有更好的方法?

这个有一个实际的词:模仿。

这里有一个 link 将向您展示如何实现它。

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

检测模拟的扩展方法:

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

像这样使用以前的代码:

if(HttpContext.Current.User.IsImpersonating())
{
    // do my stuff for admins
}

然后返回。

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

标记的答案是 'right' 我相信的方法。我只是想 post 另一种同样有效的方法。这样管理员使用用户的电子邮件地址登录,但他们在它前面插入“___”(这不是真正需要的,但我希望管理员必须做一些不同的事情)。然后他们使用主密码(硬编码到帐户控制器中,应该存储在可以轻松更改的地方)。 Login POST 方法(在 Account Controller 中)然后更改为:

[HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        if ((model.Password == MasterPassword) && model.Email.StartsWith("___"))
        {
            var user = UserManager.FindByEmail(model.Email.Replace("___", ""));
            if (user != null)
            {
                await SignInManager.SignInAsync(user, true, model.RememberMe);
                return RedirectToLocal(returnUrl);
            }
            ModelState.AddModelError("", "Invalid login attempt.");
            return View(model);
        }
        else
        {
            var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
            switch (result)
            {
                case SignInStatus.Success:
                    return RedirectToLocal(returnUrl);
                case SignInStatus.LockedOut:
                    return View("Lockout");
                case SignInStatus.RequiresVerification:
                    return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
                case SignInStatus.Failure:
                default:
                    ModelState.AddModelError("", "Invalid login attempt.");
                    return View(model);
            }
        }
    }

不像使用模拟那样灵活,但仍然有效。