0

我有一个 C# windows 应用程序,当我访问文件共享上的文件时,我需要模拟一个用户 ID,而不是用户登录的用户 ID。我使用模拟切换到该用户,然后切换回来。我还需要恢复为登录用户来访问本地文件。我得到了一个 System.ExecutionEngineException ,它没有被应用程序捕获,它只是停止了。这是代码。任何想法为什么我会收到此错误或有关如何做得更好的建议。

编辑:该应用程序使用 DevExpress 的 XAF 框架。

public static class Impersonation
{
    #region Fields
    public static WindowsImpersonationContext newUser;
    public static string domain;
    public static string userName;
    public static string password;
    #endregion
    // group type enum
    private enum SECURITY_IMPERSONATION_LEVEL : int
    {
        SecurityAnonymous = 0,
        SecurityIdentification = 1,
        SecurityImpersonation = 2,
        SecurityDelegation = 3
    }
    // obtains user token
    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

    // closes open handes returned by LogonUser
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    private extern static bool CloseHandle(IntPtr handle);

    // creates duplicate token handle
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

    #region Methods
    public static void RevertUser()
    {
        newUser.Undo();
    }
    #region ImpersonateApexApplicationUser
    /// <summary>
    /// Attempts to impersonate a user.  If successful, returns 
    /// a WindowsImpersonationContext of the new users identity.
    /// </summary>
    /// <param name="sUsername">Username you want to impersonate</param>
    /// <param name="sDomain">Logon domain</param>
    /// <param name="sPassword">User's password to logon with</param></param>
    /// <returns></returns>
    public static void ImpersonateApexApplicationUser()
    {
        // initialize tokens
        IntPtr pExistingTokenHandle = new IntPtr(0);
        IntPtr pDuplicateTokenHandle = new IntPtr(0);
        pExistingTokenHandle = IntPtr.Zero;
        pDuplicateTokenHandle = IntPtr.Zero;

        try
        {
            const int LOGON32_PROVIDER_DEFAULT = 0;
            const int LOGON32_LOGON_INTERACTIVE = 2;

            if (!LogonUser(userName, domain, Encryption.Decrypt(password), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref pExistingTokenHandle))
                throw new Exception(string.Format("LogonUser() failed with error code {0}", Marshal.GetLastWin32Error()));
            else
                if (!DuplicateToken(pExistingTokenHandle, (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, ref pDuplicateTokenHandle))
                {
                    int errorCode = Marshal.GetLastWin32Error();
                    CloseHandle(pExistingTokenHandle); // close existing handle
                    throw new Exception(string.Format("DuplicateToken() failed with error code: {0}", errorCode));
                }
                else
                {
                    // create new identity using new primary token
                    WindowsIdentity newId = new WindowsIdentity(pDuplicateTokenHandle);
                    newUser = newId.Impersonate();
                }
        }

        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            // close handle(s)
            if (pExistingTokenHandle != IntPtr.Zero)
                CloseHandle(pExistingTokenHandle);
            if (pDuplicateTokenHandle != IntPtr.Zero)
                CloseHandle(pDuplicateTokenHandle);
        }
    }
    #endregion

}

我在程序开始时这样称呼它一次:

    Impersonation.domain = "xxxx";
    Impersonation.userName = "xxxx;
    Impersonation.password = "xxxx";
    Impersonation.ImpersonateApexApplicationUser();

接着:

Impersonation.ImpersonateApexApplicationUser(); 
//file share access code
Impersonation.RevertUser();
4

0 回答 0