0

In my ASP.net MVC project I've got (among other roles) moderators and users. I want to give the moderators the option to "see current page as user".

My approach is to create a ActionFilterAttribute and overload OnActionExecuting & OnResultExecuted as the page is then rendered for the given user.

The first idea there was to juggle with the Roles:

OnActionExecuting {
  ... //various checks, if role exist, if user want to switch
  var tempRoles = Roles.getRolesForUser(user);
  filterContext.HttpContext.Items["tempRole"] = tempRoles;
  Roles.RemoveUserFromRoles(user, tempRoles)
  Roles.AddUserToRole(user, targetRole);
}

and then

OnResultExecuted {
//if switched view
{
   Roles.RemoveUserFromRole(user,targetRole)
   Roles.AddUserToRoles(filterContext.HttpContext.Items["tempRole"])
}

This works, but in a worst case scenario the roles are gone, so i prefer to not touch them...

My second idea was to create a dummy user add him to the userroles sign the moderator into this account with FormsAuthentication.SetAuthCookie(dummyUser, true) and revert everything in the OnResultExecuted, so in a worst case scenario the user is in the dummyRole (where he can logout) and the dummyUser is in the Database.

After debugging and researching I realised that SetAuthCookie requires a Redirect to come into effect - so it doesn't work this way.

The questions:

  • Is there a way to force SetAuthCookie to come into affect without a redirect
  • Any other suggestion/approaches how to accomplish this "see page as other user"?
  • If my first idea is the only solution, how do i make it foolproof?
Vulcano
  • 415
  • 10
  • 25

1 Answers1

1

Ahoi Christian,

you could decorate the class SqlRoleProvider and add it to the role manager.

See Sample Role-Provider Implementation: http://msdn.microsoft.com/en-us/library/tksy7hd7%28v=vs.100%29.aspx

The decorated SqlRoleProvider could overwrite the IsUserInRole method and thereby implement impersonation functionality.

edit: I have added the code below:

public class MyRoleProvider : SqlRoleProvider
{
    private static ConcurrentDictionary<string, string> impersonationList;

    public MyRoleProvider() : base()
    {
        impersonationList = new ConcurrentDictionary<string, string>();
    }

    public static void startImpersonate(string username, string rolename)
    {
        impersonationList.TryAdd(username,rolename);
    }

    public override string[] GetRolesForUser(string username) {
        if (impersonationList.ContainsKey(username))
            return new string[] { impersonationList[username] };
        else
            return base.GetRolesForUser(username);
    }

    public static void stopImpersonate(string username)
    {
        string rolename;
        impersonationList.TryRemove(username, out rolename);
    }
}
Vulcano
  • 415
  • 10
  • 25
Harry Berry
  • 318
  • 1
  • 10