2009-07-28 4 views
2

다른 도메인의 컴퓨터에서 공유 파일을 읽어야하는 C# 콘솔 응용 프로그램이 있습니다. 응용 프로그램이 파일에 액세스하려고하면 로컬 사용자에게 공유 리소스에 대한 액세스 권한이 없으므로 예외가 발생합니다.다른 사용자와 도메인에서 공유 파일을여시겠습니까?

현재 실행에서 공유 폴더를 열고 Windows 인증 대화 상자에 사용자 이름과 암호를 입력 한 다음 응용 프로그램을 실행하여 수동으로이 문제를 극복했습니다.

프로그래밍 방식으로 어떻게 할 수 있습니까?

답변

0

메모리에서 Windows API 호출을 사용하고 다른 도메인의 사용자로 로그인해야합니다. 예를 들어 link을 참조하십시오.

다른 아이디어는 RunAs 명령 줄 인수를 사용하여 파일을 읽고 로컬 도메인/서버의 파일에 저장하는 것입니다.

+0

두 가지로 RunAs를 사용할 수 없습니다. 로컬 컴퓨터에이 사용자가 없으며 도메인에 속하지 않습니다. 두 번째로 파일을 로컬로 복사하는 것이 매우 큽니다. "a"에 대해 –

3

a) LOGON32_LOGON_NEW_CREDENTIALS을 사용하여 LogonUser을 호출하고 새 토큰을 사용하여 WindowsIdentity을 새로 작성한 다음 일반 파일 액세스를 사용하십시오.

b) p/invoke WNetAddConnection3. 이렇게하면 시스템의 다른 모든 프로세스에서 원격 공유에 액세스 할 수 있습니다.

c) System.ManagementCIM_DataFile을 통한 WMI; p/invoke가 필요하지 않습니다. System.Management을 사용하면 원격 시스템에 대한 자격 증명을 지정할 수 있습니다.

+0

msdn은 을 말합니다. "LogonUser를 사용하여 원격 컴퓨터에 로그온 할 수 없습니다." –

+0

실제로 편집 할 수 있습니다. –

+0

우수! 나는 다른 도메인 w/no 신뢰와 솔루션에 대한 원격 컴퓨터에 인증을 찾고 있었는데 나를 위해 일했다. LogonUser에 의해 반환 된 토큰이 LOGIC32_LOGON_NEW_CREDENTIALS가 기본 토큰 인 것처럼 보입니다. WindowsIdentity.Impersonate (토큰) –

2

나는 점 "안톤은"제안 "에"내가는 Win32 API와 둘째를 사용하여 첫 번째는 WindowsIdentity 클래스를 사용하여, 하나 개의 클래스에 대한 두 가지 버전을 개발을 사용

버전 1 :

class UserImpersonation:IDisposable 
    {  
     [DllImport("advapi32.dll")] 
      public 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)] 
      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); 

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

      WindowsImpersonationContext wic; 
      string _userName; 
      string _domain; 
      string _passWord; 
      public UserImpersonation(string userName, string domain, string passWord) 
      { 
       _userName = userName; 
       _domain = domain; 
       _passWord = passWord; 
      } 
      public bool ImpersonateValidUser() 
      { 
       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); 
          wic = wi.Impersonate(); 
          if (wic != null) 
          { 
           CloseHandle(token); 
           CloseHandle(tokenDuplicate); 
           return true; 
          } 
         } 
        } 
       } 
       if (token != IntPtr.Zero) 
        CloseHandle(token); 
       if (tokenDuplicate != IntPtr.Zero) 
        CloseHandle(tokenDuplicate); 
       return false; 
      } 

     #region IDisposable Members 
      public void Dispose() 
      { 
       if(wic != null) 
       wic.Dispose(); 
       RevertToSelf(); 

      } 
      #endregion 
    } 

버전 2

012,351,641
class UserImpersonation2:IDisposable 
    { 
     [DllImport("advapi32.dll")] 
     public static extern bool LogonUser(String lpszUserName, 
      String lpszDomain, 
      String lpszPassword, 
      int dwLogonType, 
      int dwLogonProvider, 
      ref IntPtr phToken); 

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

     WindowsImpersonationContext wic; 
     IntPtr tokenHandle; 
     string _userName; 
     string _domain; 
     string _passWord; 

     public UserImpersonation2(string userName, string domain, string passWord) 
     { 
      _userName = userName; 
      _domain = domain; 
      _passWord = passWord; 
     } 

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

     public bool ImpersonateValidUser() 
     { 
      bool returnValue = LogonUser(_userName, _domain, _passWord, 
        LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, 
        ref tokenHandle); 

      Console.WriteLine("LogonUser called."); 

      if (false == returnValue) 
      { 
       int ret = Marshal.GetLastWin32Error(); 
       Console.WriteLine("LogonUser failed with error code : {0}", ret); 
       return false; 
      } 

      Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No")); 
      Console.WriteLine("Value of Windows NT token: " + tokenHandle); 

      // Check the identity. 
      Console.WriteLine("Before impersonation: " 
       + WindowsIdentity.GetCurrent().Name); 
      // Use the token handle returned by LogonUser. 
      WindowsIdentity newId = new WindowsIdentity(tokenHandle); 
      wic = newId.Impersonate(); 

      // Check the identity. 
      Console.WriteLine("After impersonation: " 
       + WindowsIdentity.GetCurrent().Name); 
      return true; 
     } 
     #region IDisposable Members 
     public void Dispose() 
     { 
      if(wic!=null) 
       wic.Undo(); 
      if (tokenHandle != IntPtr.Zero) 
       CloseHandle(tokenHandle); 

     } 
     #endregion 
    } 

어떻게 (모두 동일)를 사용하는 (작은 변화와 MSDN에서)
  const string file = @"\\machine\test\file.txt"; 

      using (UserImpersonation user = new UserImpersonation("user", "domain", "password")) 
      { 
       if (user.ImpersonateValidUser()) 
       { 
        StreamReader reader = new StreamReader(file); 
        Console.WriteLine(reader.ReadToEnd()); 
        reader.Close(); 
       } 
      } 
+0

사용자가 원격 컴퓨터의 로컬 사용자이거나 사용자가 도메인 사용자이고 로컬 컴퓨터가 도메인에 없습니다. –

+0

디버깅 할 때 도메인 (예 : localhost) – msysmilu

관련 문제