日期:2010-12-15  浏览次数:20397 次

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Principal;
using System.Runtime.InteropServices;

public class Impersonate
{
    #region 模拟
    private WindowsImpersonationContext impersonationContext;

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

    [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
    private static extern int LogonUser(String lpszUserName, String lpszDomain, String lpszPassword,
                  int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

    [DllImport("advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
    private extern static int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);

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

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

    /// <summary>
    /// 模拟一个用户
    /// </summary>
    /// <param name="userName">用户名</param>
    /// <param name="password">密码</param>
    /// <param name="domain">域名/计算机名</param>
    /// <returns>true 模拟成功,false 模拟失败</returns>
    public bool ImpersonateUser(string userName, string password, string domain)
    {
        WindowsIdentity wi;
        IntPtr token = IntPtr.Zero;
        IntPtr tokenDuplicate = IntPtr.Zero;
        if (RevertToSelf())
        {
            if (LogonUser(userName, domain, password,
                        LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
            {
                if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                {
                    wi = new WindowsIdentity(tokenDuplicate);
                    impersonationContext = wi.Impersonate();
                    if (impersonationContext != null)
                    {
                        CloseHandle(tokenDuplicate);
                        CloseHandle(token);