I want to share with you some useful code snippet, which i use in my own project for user impersonation.
take a look on it:
[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
internal class MySafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private MySafeTokenHandle()
: base(true)
{
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
override protected bool ReleaseHandle()
{
return NativeMethods.CloseHandle(handle);
}
}
[SuppressUnmanagedCodeSecurity()]
internal static class NativeMethods
{
#region P/Invoke
internal const int LOGON32_LOGON_INTERACTIVE = unchecked((int)2);
internal const int LOGON32_PROVIDER_DEFAULT = unchecked((int)0);
[DllImport("advapi32.dll")]
internal static extern int LogonUserA(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
out MySafeTokenHandle phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern int DuplicateToken(MySafeTokenHandle hToken,
int impersonationLevel,
out MySafeTokenHandle hNewToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static extern bool CloseHandle(IntPtr handle);
#endregion
}
[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
public class Impersonation : IDisposable
{
WindowsImpersonationContext impersonationContext;
public void ImpersonateUser(String userName, String domain, String password)
{
WindowsIdentity tempWindowsIdentity;
MySafeTokenHandle token;
MySafeTokenHandle tokenDuplicate;
if (NativeMethods.LogonUserA(userName, domain, password, NativeMethods.LOGON32_LOGON_INTERACTIVE, NativeMethods.LOGON32_PROVIDER_DEFAULT, out token) != 0)
{
using (token)
{
if (NativeMethods.DuplicateToken(token, 2, out tokenDuplicate) != 0)
{
using (tokenDuplicate)
{
if (!tokenDuplicate.IsInvalid)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate.DangerousGetHandle());
impersonationContext = tempWindowsIdentity.Impersonate();
return;
}
}
}
}
}
else
throw new Exception("LogonUser failed: " + Marshal.GetLastWin32Error().ToString());
}
public void Dispose()
{
impersonationContext.Undo();
GC.SuppressFinalize(this);
}
}
public class ImpersonationExecutor
{
public string USR { get; set; }
public string DOMAIN { get; set; }
public string PWD { get; set; }
public ImpersonationExecutor(string userName, string domainName, string password)
{
USR = userName;
DOMAIN = domainName;
PWD = password;
}
public void ExecuteCode<t>(Action<t> action, T arg)
{
using (Impersonation user = new Impersonation())
{
user.ImpersonateUser(USR, DOMAIN, PWD);
action(arg);
}
}
}
public class ImpersonationFactory
{
public static ImpersonationExecutor Create(string UserName, string Domain, string Password)
{
return new ImpersonationExecutor(UserName, Domain, Password);
}
}
USage:
string from = "from";
string to = "to";
byte[] buffer = null;
ImpersonationFactory.Create("userA", "domainA", "passwordA").ExecuteCode<string>(delegate(string path) { buffer = File.ReadAllBytes(path); }, from);
ImpersonationFactory.Create("userB", "domainB", "passwordB").ExecuteCode<string>(delegate(string path) { File.WriteAllBytes(path, buffer); }, to);
</string></string></t></t>