using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text.RegularExpressions;
namespace Update
{
public class ImpersonateHelper
{
[DllImport("advapi32.dll", SetLastError = true)]
public extern static bool LogonUser(String lpszUsername, String lpszDomain,
String lpszPassword, int dwLogonType,
int dwLogonProvider, ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
public delegate void ImpersonatedWork();
//// <summary>
/// 以指定用户的身份去做一件事情
/// </summary>
/// <param name="UserName"></param>
/// <param name="PWD"></param>
/// <param name="WhatToDo"></param>
public static void ImpersonateAndDo(string UserName, string PWD, ImpersonatedWork WhatToDo)
{
string domainName = string.Empty;
string userName = string.Empty;
IntPtr tokenHandle = new IntPtr(0);
IntPtr dupeTokenHandle = new IntPtr(0);
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_INTERACTIVE = 2;
const int SecurityImpersonation = 2;
if (!Regex.IsMatch(UserName, @"^\w+[\\]?\w+$"))
{
throw new ApplicationException("非法的用户名");
}
string[] tmp = UserName.Split(new char[] { '\\' });
if (tmp.Length > 1)
{
domainName = tmp[0];
userName = tmp[1];
}
else
{
userName = tmp[0];
}
tokenHandle = IntPtr.Zero;
dupeTokenHandle = IntPtr.Zero;
bool returnValue = LogonUser(userName, domainName, PWD,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
ref tokenHandle);
if (!returnValue)
{
throw new ApplicationException("取Handle出错了!");
}
//Console.WriteLine("当前用户是: "
// + WindowsIdentity.GetCurrent().Name);
bool retVal = DuplicateToken(tokenHandle, SecurityImpersonation, ref dupeTokenHandle);
if (!retVal)
{
CloseHandle(tokenHandle);
throw new ApplicationException("复制Handle出错了!");
}
WindowsIdentity newId = new WindowsIdentity(dupeTokenHandle);
WindowsImpersonationContext impersonatedUser = newId.Impersonate();
if(WhatToDo!=null)
WhatToDo();
impersonatedUser.Undo();
if (tokenHandle != IntPtr.Zero)
CloseHandle(tokenHandle);
if (dupeTokenHandle != IntPtr.Zero)
CloseHandle(dupeTokenHandle);
}
}
}