A Framework for Application Level Impersonation Using the ASP.NET Membership Provider

In web applications that allow users to create accounts and login, it’s very common for developers to provide some way for an administrator to impersonate / emulate another user.  Below is a framework for doing this using the ASP.NET Membership and Profile provider classes.  This solution is simply a wrapper around these same classes that will produce cleaner code if you need to include an impersonation feature in your app.  I recently used this in a 100K eCommerce application for one of my clients with great success.  Hope you like it!

Below are a couple of examples.  Scroll down even further for a description of the members of the two CS files: AppMembership.cs and AppProfile.cs.

Example 1


//This line displays the name of the currently logged in user using .NET membership provider:
Response.Write(Membership.GetUser().UserName);

//…and this line does the same thing using the AppMembership wrapper class:
Response.Write(AppMembership.User.UserName);

//Until you start impersonation:
AppMembership.StartImpersonation(“bob”); 

//Now, this line displays the name of the impersonated user:
Response.Write(AppMembership.User.UserName);

//…and this line uses the wrapper class to display the name of the currently logged in user:
Response.Write(Membership.GetUser().UserName);



Example 2


//display current user’s username
Response.Write(AppMembership.User.UserName);

//start impersonating Bob
AppMembership.StartImpersonation(“Bob”); 

//the same code now displays Bob’s user name
Response.Write(AppMembership.User.UserName);

//display current user’s name (while still impersonating Bob)
Response.Write(Membership.GetUser().UserName);

//end impersonation
AppMembership.EndImpersonation();

//the same code now displays the current user’s name
Response.Write(AppMembership.User.UserName);

File (1 of 2): AppProfile.cs


// Returns boolean value indicating whether a user is currently being impersonated.
static bool IsUserBeingImpersonated

// Returns a MembershipUser object for either:
// a) the logged in user
// b) the user currently being impersonated, regardless of who is logged in.

static MembershipUser User

//Returns the MembershipUser object of the impersonator
static MembershipUser Impersonator 

// Returns boolean value to determine:
// a) Whether the logged in user is in the specified role
// b) If impersonating a user, whether the user currently being impersonated is in the specified role
static bool IsUserInRole(string roleName) 

// Returns array of strings containing:
// a) Roles the currently logged in user is a member of.
// b) If admin is emulating a user, roles the emulated user is a member of.

static string[] GetRolesForUser(string roleName)

// Start impersonating the specified user
static void StartImpersonation(string UserName)

// Stop impersonating a user
static void EndImpersonation()

File (2 of 2): AppProfile.cs


// Gets the profile of the current user.
// Since this may not always be the logged in user, query the ProfileCommon object
// for the AppMembership.User user, which will always be:
// a) the logged in user
// b) the user currently being impersonated, regardless of who is logged in.
static ProfileCommon UserProfile

// Gets the profile of the specified user.
static ProfileCommon GetUserProfile(string UserName)

// This will cause it to be retrieved and cached again when the UserProfile property is accessed again.
static void Clear()

Desktop “No Support”

Haha.  I work for a small development firm.  We don’t… really… have a desktop support person.  The HR guy needs more memory and has been scrounging for parts for a couple of weeks now, and he just sent this email out to the developers:

Subject: Who Want’s to Make $50.00

Body: “I need a new computer with more memory.  There are currently 3 unused computers here.  Use whichever one works and change my computer out for one of those with more memory. First one to accept, has the contractJ

Creating multiple sites in IIS on Windows XP

How did it take me this long to find a way to do this?  We all know that Windows XP Pro shipped without the ability to create multiple web sites in IIS.    Although the ”new site” menu item is missing, the feature is still supported by the OS.  You can create additional sites manually, and it’s easy.  I’ve found two good ways to do this:

1) Put this in a .bat or .cmd file and keep incrementing the number “2″ each time you create a new site.

c:
cd c:\Inetpub\AdminScripts
cscript.exe adsutil.vbs create_vserv W3SVC/2
pause

2) Download this tool. It’s free and it’s cool.  It provides a nice UI but probably just runs the above script.

Windows PowerShell 1.0 – Yay!

Windows PowerShell by Microsoft is available in RC2 here!

You can also win great prizes here! Yay! 

Ok, I’m not really that excited.  This is basically a souped-up rewrite of the age-old cmd.exe, but it does look interesting enough and is worth a 2nd look.  I just downloaded it and may get a little more upbeat about this after I play with its wonderfulness for a few minutes. After all, there’s even an SDK for this thing! wow.

Also visit the PowerShell web site  for more propaganda information.

FormView control, SqlDataSource, and ‘Procedure or function has too many arguments specified’ error

I ran into this problem today because sometimes the FormView control will pass more parameters to your stored procedure than it will accept (using SqlDataSource). 

Here’s some more info on the error: http://geekswithblogs.net/chrishan/archive/2005/07/02/45278.aspx

The best solution I could come up with is below.  Before the insert, the command arguments are inspected and any that are not in the <InsertParameters> collection are discarded.


public void MessageDataSource_OnInserting(object sender, SqlDataSourceCommandEventArgs e)
{

//Remove insert parameters that .NET is attempting to pass
//if they are not defined in the SqlDataSource InsertParameters list.
foreach (DbParameter param in e.Command.Parameters)
{

if (MessageDataSource.InsertParameters[param.ParameterName] == null)
    e.Command.Parameters.RemoveAt(param.ParameterName);

}

}

WinMerge!

This little gem really saved my taters today.  It’s a nice little open source (free) file comparison tool that can also compare directories (much faster than a different tool I just uninstalled). 

 It also has a nifty archive feature that lets you archive only different files (including unique files) from both sides.  So your pre-deployment backup doesn’t have to be huge. 

To get it, go to http://www.winmerge.org/