Presenting WindowsIdentityHelper
One of the difficulties of using the WindowsIdentity class is the fact that it requires a handle (IntPtr) to a Windows Security Token. Using the LogonUser functionality we can get a hold of such a handle
[DllImport(Advapi32File, CharSet = DefaultCharSet, SetLastError = DefaultSetLastError)]
public static extern bool LogonUser( /* other parameters */, out IntPtr userTokenHandle);
The easiest way to avoid memory leaks is to implement a custom SafeHandle
public class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
protected internal SafeTokenHandle()
: base(true)
{
}
protected override bool ReleaseHandle()
{
if(!this.IsInvalid)
{
return NativeMethods.CloseHandle(this.handle);
}
return true;
}
}
With that SafeHandle in place we can change the signature to
[DllImport(Advapi32File, CharSet = DefaultCharSet, SetLastError = DefaultSetLastError)]
public static extern bool LogonUser( /* other parameters */, out SafeTokenHandle userTokenHandle);
With the Be.Timvw.Framework.Security.Principal.WindowsIdentityHelper we can now easily obtain a WindowsIdentity and use it to do some impersonation
using(WindowsIdentityHelper windowsIdentityHelper = new WindowsIdentityHelper(username, domain, password))
using(windowsIdentityHelper.GetWindowsIdentity().Impersonate())
{
File.WriteAllText(@"c:\temp\blah.txt", "hello there");
}