因為之前的需求用Javascript呼叫client的程式

然後client程式去開啟遠端的檔案

但是遠端的目錄只限制不可以任意打開

所以只好用模擬帳號的方式用程式去開檔案

//要先Using 
using System.Runtime.InteropServices;
using System.Security.Principal;

//先引用API
public const int LOGON32_LOGON_NEW_CREDENTIALS = 9; //直接存取網路芳鄰
public const int LOGON32_LOGON_INTERACTIVE = 2;     //電腦存在於網域
public const int LOGON32_PROVIDER_DEFAULT = 0;

WindowsImpersonationContext impersonationContext;

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public 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)]
public extern static int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);

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

private void Form1_Load(object sender, EventArgs e)
{
  //恢復狀態
  if (RevertToSelf()) 
  {
      if (impersonateValidUser("帳號", "Domain Or 網芳位置", "密碼"))
      {
          //......要處理的事件
          undoImpersonation();
      }
      else
          MessageBox.Show("***無法登入**");
  }
}

//電腦存在於網域的驗證
private bool impersonateValidUser(string userName, string domain, string password)
{
    WindowsIdentity tempWindowsIdentity;
    IntPtr token = IntPtr.Zero;
    IntPtr tokenDuplicate = IntPtr.Zero;
    if (LogonUser(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)
                return true;
            else
                return false;
        }
        else
            return false;
    }
    else
        return false;
}

//直接存取網路芳鄰的驗證
private bool impersonateValidUser(string userName, string domain, string password)
{
    WindowsIdentity tempWindowsIdentity;
    IntPtr token = IntPtr.Zero;
    IntPtr tokenDuplicate = IntPtr.Zero;
    if (LogonUser(userName, domain, password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
    {
        if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
        {
            tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
            impersonationContext = tempWindowsIdentity.Impersonate();
            if (impersonationContext != null)
                return true;
            else
                return false;
        }
        else
            return false;
    }
    else
        return false;
}

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

如果是Web的話

System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext = ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();

//......要處理的事件

impersonationContext.Undo();

Logon type 2 Interactive 本地登錄。最常見的登錄方式。

Logon type 3 Network 網絡登錄- 最常見的是訪問網絡共享文件夾或打印機。 IIS的認證也是Type 3

Logon type 4 Batch 計劃任務

Logon Type 5 Service 服務

.......等等參考這裡...

參考:

http://support.microsoft.com/kb/306158/zh-tw

http://blog.darkthread.net/post-2009-11-20-impersonate.aspx

http://msdn.microsoft.com/en-us/library/windows/desktop/aa378184%28v=vs.85%29.aspx

arrow
arrow
    全站熱搜

    鴨爸 發表在 痞客邦 留言(0) 人氣()