views:

202

answers:

4

The System.Security.Principal.WindowsIdentity.Impersonate function takes a System.intptr parameter, which seems awfully useless in my situation (with my limited understanding).

I am developing an intranet application that uses integrated security to authorize users page-by-page against a role associated with their Windows Identity. I have no passwords or anything of the sort. Simply a Windows username. For testing purposes, how could I possibly impersonate a Windows user based on their username? The "impersonate" method jumped out at me as obvious, but it takes an unexpected parameter.

Thanks in advance :)

A: 

User tokens (the value that the IntPtr in Impersonate represents) represent more than the username. They are a handle into an internal windows context that include information about the user, authentication tokens, current security rights, etc. It's because of this that you can't impersonate without a password. You have to actually "log in" to create a token via the LogonUser method.

What I've done in the past is create a special "Test" user account with a password that I can just keep in code or a config file.

Paul Alexander
I'm not sure that this solution would be possible under the circumstances. Since I entered late into the development cycle, I was forced to hack around the system to avoid changing tables and infrastructure. I use the WindowsIdentity.getCurrent() object and match that string against a "Username" column. The table cannot store any information about the user's Windows account, besides their username.
Chris
A: 

You shouldn't need to impersonate to check role membership. Simply use the constructor for a WindowsIdentity that takes a UPN (userPrincipalName) constructed from the username according to your UPN conventions, then create a WindowsPrincipal from that identity and use IsInRole to check membership in a group. This works on W2K3 and a Windows 2003 domain, but not in other circumstances.

var userIdentity = new WindowsIdentity( username + "@domain" );
var principal = new WindowsPrincipal( userIdentity );
var inRole = principal.IsInRole( "roleName" );

You may also want to consider using either the standard or a custom role provider that will allow you to use the Roles interface to check membership.

tvanfosson
+2  A: 

In a nutshell, no. But you are on the right track. You either have to get the user by simulating a login with LoginUserA ( C Win32 Api ) or set your IIS site to Windows Authentication.

In that case, your Page will have a property named User of type IPrincipal, which you can then use to run as that user. For example ( sorry, C# code ).

IPrincipal p = this.User;
WindowsIdentity id = (WindowsIdentity)p.Identity;
WindowsImpersonationContext wic = id.Impersonate();
try {
    // do stuff as that user
}
finally {
     wic.Undo();
}
Serapth
+1  A: 

Are you using anything windows-specific from the WindowsPrincipal or is it just a handy way to get auth/auth without having to manage users? If you need to be windows-based, Serapth has the right method. If you are just really using it as a convenient auth/auth store, then you should probably write your code to interface with IPrincipal. You can then inject your own implementations of IPrincipal with the desired values into either the HttpContext.User or Thread.CurrentThread.Principal depending on the nature of your tests and app.

Wyatt Barnett