使用LogonUser进行模拟但仍然获得UnauthorizedAccessException

时间:2017-08-07 11:24:09

标签: c# windows active-directory

开始编辑

我使用dwLogonType = 9(LOGON32_LOGON_NEW_CREDENTIALS)和dwLogonProvider = 3(LOGON32_PROVIDER_WINNT50)

结束修改

我正在尝试以USER_A身份登录时模拟USER_B。模拟的目的是访问网络共享上的资源(以防万一,类似于\ host_b \ folder $ \ subfolder_1 \ subfolder_2 \ file_b.JPG)

USER_A无权写入file_b.JPG。 USER_B(我通过使用USER_B凭据登录host_b进行了测试)。

但是,在模仿USER_B之后,当写入file_b.JPG时,我会遇到System.UnauthorizedAccessException异常。

我不知道会出现什么问题,特别是在其他情况下,假冒行为完美无瑕。

我用来模拟的代码如下,通过创建Impersonator的新实例

namespace Util.Impersonation
{

    public class Impersonator : IDisposable
    {

        private static readonly ILog logger = LogManager.GetLogger(typeof(Impersonator));


        public Impersonator(
            string userName,
            string domainName,
            string password)
        {
            ImpersonateValidUser(userName, domainName, password);
        }

        public void Dispose()
        {
            UndoImpersonation();
        }

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

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern 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 static extern bool CloseHandle(IntPtr handle);

        private void ImpersonateValidUser(
            string userName,
            string domain,
            string password)
        {
            WindowsIdentity tempWindowsIdentity = null;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;

            logger.Info($"Trying to impersonate {userName}@{domain}.");
            try
            {
                if (RevertToSelf())
                {
                    if (LogonUser(userName,
                                  domain,
                                  password,
                                  Settings.Impersonation_dwLogonType,
                                  Settings.Impersonation_dwLogonProvider,
                                  ref token) != 0)
                    {
                        if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                        {
                            tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                            impersonationContext = tempWindowsIdentity.Impersonate();

                            logger.Info($"Succesfully impersonating {userName}@{domain}.");
                        }
                        else
                        {
                            LogErrorAndThrow();
                        }
                    }
                    else
                    {
                        LogErrorAndThrow();
                    }
                }
                else
                {
                    LogErrorAndThrow();
                }
            }
            finally
            {
                if (token != IntPtr.Zero)
                {
                    CloseHandle(token);
                }

                if (tokenDuplicate != IntPtr.Zero)
                {
                    CloseHandle(tokenDuplicate);
                }
            }
        }

        private void LogErrorAndThrow()
        {
            var exception = new Win32Exception(Marshal.GetLastWin32Error());
            logger.ErrorFormat("There was a problem during impersonation: {0}", exception);
            throw exception;
        }

        private void UndoImpersonation()
        {
            if (impersonationContext != null)
            {
                logger.Info($"Trying to undo impersonation.");
                impersonationContext.Undo();
                logger.Info($"Succesfully undo impersonation.");
            }
        }

        private WindowsImpersonationContext impersonationContext = null;
    }
}

先谢谢!

0 个答案:

没有答案