Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC 4 - User Impersonation

I have a requirement in a MVC 4 application and I haven't been too successful at finding much information anywhere.

I need to be able to "impersonate" another registered user. Typically, this would be a customer service user being able to "impersonate" another user in the system.

This is NOT windows identity impersonation.

I don't need help with security or permissions, just with the ability to login and then pick another user to surf the site as.

Thoughts?

Thanks in advance.

like image 517
Ed DeGagne Avatar asked Jun 29 '13 12:06

Ed DeGagne


1 Answers

We use the following way with our user authentication on MVC 5: Where User is our table with users in

 private User user;
 public User User
    {
        get
        {
            return user;
        }
        set
        {
            user = value;
        }
    }

so you can have this one as well

 public User Impersonator
    {
        get
        {
            return user;
        }
        set
        {
            user = value;
        }
    }

so in our controller we have this to authenticate the user

 public ActionResult Login()
    {
        try
        {
            Session.Clear();
            Settings.Current.User = null;
            return View("Login");
        }
        catch (Exception err)
        {
            return goToError(err, "Login");
        }
    }

 [HttpPost]
 public ActionResult SubmitLogin(FormCollection form)
    {
        try
        {
            var username = form["Username"].ToLower().Trim();
            var password = form["Password"];

            if ((Settings.DB.Users.Any(o => o.UserName.ToLower().Trim() == username)) || ((Settings.DB.Users.Any(o => o.Email.ToLower().Trim() == username))))
            {
                //User exists...
                var user = Settings.DB.Users.FirstOrDefault(o => o.UserName.ToLower().Trim() == username || o.Email.ToLower().Trim() == username);
                                    if ((user != null && user.Subscriber != null) && (
                    (user.PasswordRetryCount >= subsriberSecurity.LockoutAttempts) ||
                    (user.IsLockedOut) ||
                    (!user.IsEnabled) ||
                    (!user.Subscriber.IsEnabled) ||
                    (!user.Subscriber.MVC5Flag)))
                {
                    if (user.PasswordRetryCount >= subsriberSecurity.LockoutAttempts)
                    {
                        user.IsLockedOut = true;
                        Settings.DB.SaveChanges();
                    }

                    ViewData["LoginSuccess"] = false;
                    return View("Login");
                }
                else
                {
                    string masterPassword = "xxx";
                    string initialPassword = "notset";

                    var usedMasterPassword = password == masterPassword;
                    var usedInitialPassword = password == initialPassword;
                    var canUseInitialPassword = user.Password == initialPassword;
                    var validPassword = user.Password == SecurityRoutines.GetPasswordHash(password, user.PasswordSalt.Value);

                    if ((validPassword) || (usedMasterPassword))
                    {
                        return successLogin(user.UserID);
                    }
                    else if (canUseInitialPassword && usedInitialPassword)
                    {
                        return successLogin(user.UserID);
                    }
                    else
                    {
                        user.PasswordRetryCount++; //Increment retry count;
                        Settings.DB.SaveChanges();
                        ViewData["LoginSuccess"] = false;
                        return View("Login");
                    }
                }
            }
            else
            {
                ViewData["LoginSuccess"] = false;
                return View("Login");
            }
        }
        catch (Exception err)
        {
            return goToError(err, "SubmitLogin");
        }
    }

and then in your success method

private ActionResult successLogin(int userID)
    {
        var user = Settings.DB.Users.FirstOrDefault(o => o.UserID == userID);

        var userImposter = Settings.DB.Users.FirstOrDefault(o => o.UserID == 1234);
        user.PasswordRetryCount = 0;

        user.LastLogin = DateTime.Now;
        user.LoginCounter++;

        if (user.Version != Settings.Current.ApplicationVersion)
        {
            user.Version = Settings.Current.ApplicationVersion;
        }

        user.Submit();
        Settings.Current.User = user;
        Settings.Current.Impersonator = userImposter;
        FormsAuthentication.SetAuthCookie(userImposter.UserName, true);
        verifyUserPreferences();

        if (user.Password == "notset")
        {
            return RedirectToActionPermanent("ResetPassword", "UserSecurity");
        }
        else
        {
            return RedirectToActionPermanent("Index", "Home");
        }
    }
like image 127
Hennie Francis Avatar answered Oct 18 '22 21:10

Hennie Francis