[ASP.NET]如何Impersonate另外的身份對UNC存取檔案

包含 c#, asp.net, vb.net, delphi.net 等 .net framework 的開發討論區
回覆文章
頭像
tim
文章: 1380
註冊時間: 2008年 11月 26日, 00:49

[ASP.NET]如何Impersonate另外的身份對UNC存取檔案

文章 tim »

使用方式為引入 API, 參考資料: http://2leggedspider.wordpress.com/2007 ... g-asp-net/

主要程式碼為如下:

代碼: 選擇全部

using System.Security.Principal;
using System.Runtime.InteropServices;

    WindowsImpersonationContext impersonationContext;

    [DllImport("advapi32.dll")]
    public static extern int LogonUserA(String lpszUserName,
        String lpszDomain,
        String lpszPassword,
        int dwLogonType,
        int dwLogonProvider,
        ref IntPtr phToken);
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int DuplicateToken(IntPtr hToken,
        int impersonationLevel,
        ref IntPtr hNewToken);

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

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

    private bool ImpersonateUser(String userName, String domain, String password)
    {
        WindowsIdentity tempWindowsIdentity;
        IntPtr token = IntPtr.Zero;
        IntPtr tokenDuplicate = IntPtr.Zero;

        if (RevertToSelf())
        {
            if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
                LOGON32_PROVIDER_DEFAULT, ref token) != 0)
            {
                if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                {
                    tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                    impersonationContext = tempWindowsIdentity.Impersonate();
                    if (impersonationContext != null)
                    {
                        CloseHandle(token);
                        CloseHandle(tokenDuplicate);
                        return true;
                    }
                }
            }
        }
        if (token != IntPtr.Zero)
            CloseHandle(token);
        if (tokenDuplicate != IntPtr.Zero)
            CloseHandle(tokenDuplicate);
        return false;
    }

    private void UndoImpersonation()
    {
        impersonationContext.Undo();        
    }

// test code
        if (ImpersonateUser("develop", "", "programmer"))
        {
            string folderPath = @"\\test_server_ip\test_folder";

            string locationToSave = folderPath + "\\" + "test_file.txt";
            try
            {
                StreamWriter sr = new StreamWriter(locationToSave);
                sr.WriteLine("test1");
                sr.WriteLine(DateTime.Now.ToString());
                sr.Close();
                Response.Write("file has been saved!");
            }
            catch (Exception ex)
            {
                Response.Write("Error: " + ex.Message);
            }

            UndoImpersonation();
        }
        else
        {
            Response.Write("Failed");
        }

多多留言, 整理文章, 把經驗累積下來.....
回覆文章