tonyellard
tonyellard

Reputation: 156

ASP.NET Implementing "Act As" functionality when using Windows Authentication and Custom Role Provider

I'm trying to implement "Act As" functionality for an ASP.NET application while at the same time using Windows Authentication and a custom role provider. Essentially what I want to be able to do is:

The scenario I'm trying to fulfill is that an application admin is attempting to assist a user with a problem and clicks the "act as" button to act as that user and see the application as they would see it. So the Role Provider would need to understand that the current user is acting as someone else and get permissions information for that user instead of the current user.

My plan was to implement an impersonation feature that would delete the roles cookie and add a value to a session variable indicating that the user is currently impersonating another user. As the session is not populated at the time that authorization occurs however, this isn't possible. I don't want to use cookies as I don't want this to cause a potentially persistent state on the admins machine (such that the admin couldn't open another window to the app and either act as another user or view their own data).

I can't find a good way (without cookies) to save the "Acting as user..." information given that the session is unavailable. I'd like to use the role provider, etc., so that I can leverage the built in security trimming in .NET. This all may simply be impossible, but I'm hoping someone out there has either tried this before or has a suggestion for something I can attempt to implement.

Thanks in advance!!

Upvotes: 1

Views: 617

Answers (2)

gbs
gbs

Reputation: 7266

I have implemented something similar...though not exactly like your scenario but pretty close.

  1. Admin Login (Has one role like Admin)

  2. Then admin is redirected to "Select Client" Page. Admin can search Client by ID, Name, etc. From the list Admin selects a Client. I store the client ID in a cookie.

  3. I have custom RolesProvider that calls my custom GetRoles(loggedinUserid);

  4. GetRoles(int loggedinUserId) method then determines the type of the user i.e. if it's Admin or non-admin. If it is admin then, fetch ClientID from cookie. Pass loggedInUserID, typdofuser and ClientId to the stored procedure that will return all roles for the admin + all roles for that ClientId and return to roles provider.

This way I have all my menuitems for Admin available as well as menus needed for ClientID.

Admin can go to "Select Client" page anytime and switch to another client. When they select a client, new ClientId will be stored in the cookie.

Now you have two options after this:

  1. You can let rolesprovider call this upon every request or

  2. Store the fetched roles in HttpCache and update this cache whenever ClientId is changed.

Hope this helps.

Upvotes: 1

hermiod
hermiod

Reputation: 1168

See my answer to a similar question here

The gist of it is:

The way I did this, which is admittedly a little crude, was to have an impersonation table in my database which contains the logon name of the user who is doing the impersonating and the logon of the user they wish to impersonate.

I added some override code so that when the user first goes to the page (it uses Windows authentication), it will check to see if that user has an impersonation set in the table and then place this user id in an object in the session state. If there was no impersonation, it would place the actual user id in this same object.

To prevent me from doing things to the user's data as them, there are two properties in this object, one for logon_name, which is what is used by the system for content-customization, and another called NameForLog, which is used when logging any actions. All actions I make will be logged as me.

All areas on the site that display user-customized content look at this session object, so they will always use the impersonated ID and therefore always show me what the user is seeing. Beyond the first page and the logging code, it doesn't even know that it is me it is dealing with.

For your scenario, you could implement a roles provider and override GetRolesForUser to return the roles for the impersonated user plus some role that will allow the impersonating user to access the impersonation functionality for the purposes of turning it off.

You could even return the impersonated user's roles with the impersonating user's roles in order to give the admin user access to all of their own features as well as the user they are impersonating, it all depends how much this would affect the usefulness of the feature in your particular scenario.

Upvotes: 1

Related Questions