Tuesday, June 10, 2008

Impersonating a user programmatically in C# code

The credit for this code goes to http://justgeeks.blogspot.com/2007/09/impersonating-user-programmatically-in_06.html
Here is how to call it....

public void SampleCallingMethod(Object s, EventArgs e)
{
if(ImpersonateUser("username", "domain", "password"))
{
//Insert your code that runs under the security context of a specific user here.
doSomethingHere();
UnImpersonation();
}
else
{
//Your impersonation failed. Therefore, include a fail-safe mechanism here.
}
}

Here is the source code....


using System;
using System.Web;
using System.Web.Security;
using System.Security.Principal;
using System.Runtime.InteropServices;

namespace AuthenticationMapper
{
///
/// Use this class to run a section of code as a different user.
/// Most of this code was copied from: http://support.microsoft.com/kb/306158
/// Modifications by: Brent Vermilion 9/5/2007
///
public class Impersonation
{

WindowsImpersonationContext impersonationContext;

#region WIN32 definitions


public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;

[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);

[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool RevertToSelf();

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);

#endregion

public Impersonation()
{

}
#region SampleUsage
public void SampleCallingMethod(Object s, EventArgs e)
{
if(ImpersonateUser("username", "domain", "password"))
{
//Insert your code that runs under the security context of a specific user here.
UnImpersonation();
}
else
{
//Your impersonation failed. Therefore, include a fail-safe mechanism here.
}
}

#endregion

public bool ImpersonateUser(String userName, String domain, String password)
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;

if(RevertToSelf())
{
if(LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if(DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if(token!= IntPtr.Zero)
CloseHandle(token);
if(tokenDuplicate!=IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}

public void UnImpersonation()
{
impersonationContext.Undo();
}

}
}

No comments: