2008-09-07 3 views
3

C#에서 간단한 Windows Forms 프로그램을 작성했습니다. 나는 Windows 사용자 이름과 암호를 입력 할 수 있고 내가 입력 한대로 입력 한 사용자로 실행되는 코드를 실행하기 위해 로그인 버튼을 클릭 할 수 있기를 원합니다.Windows Forms 프로그램 실행을위한 사용자 변경

답변

4

WindowsIdentity.Impersonate 메서드를 사용하여 을 사용할 수 있습니다. 이 방법을 사용하면 코드가 다른 Windows 사용자로 가장 할 수 있습니다. 여기에 좋은 샘플이 방법에 대한 자세한 내용은 링크입니다 :

http://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity.impersonate.aspx

전체 예제 :

// This sample demonstrates the use of the WindowsIdentity class to impersonate a user. 
// IMPORTANT NOTES: 
// This sample can be run only on Windows XP. The default Windows 2000 security policy 
// prevents this sample from executing properly, and changing the policy to allow 
// proper execution presents a security risk. 
// This sample requests the user to enter a password on the console screen. 
// Because the console window does not support methods allowing the password to be masked, 
// it will be visible to anyone viewing the screen. 
// The sample is intended to be executed in a .NET Framework 1.1 environment. To execute 
// this code in a 1.0 environment you will need to use a duplicate token in the call to the 
// WindowsIdentity constructor. See KB article Q319615 for more information. 

using System; 
using System.Runtime.InteropServices; 
using System.Security.Principal; 
using System.Security.Permissions; 
using System.Windows.Forms; 

[assembly:SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode=true)] 
[assembly:PermissionSetAttribute(SecurityAction.RequestMinimum, Name = "FullTrust")] 
public class ImpersonationDemo 
{ 
    [DllImport("advapi32.dll", SetLastError=true, CharSet = CharSet.Unicode)] 
    public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, 
     int dwLogonType, int dwLogonProvider, ref IntPtr phToken); 

    [DllImport("kernel32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)] 
    private unsafe static extern int FormatMessage(int dwFlags, ref IntPtr lpSource, 
     int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr *Arguments); 

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

    [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] 
    public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, 
     int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle); 

    // Test harness. 
    // If you incorporate this code into a DLL, be sure to demand FullTrust. 
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] 
    public static void Main(string[] args) 
    { 
     IntPtr tokenHandle = new IntPtr(0); 
     IntPtr dupeTokenHandle = new IntPtr(0); 
     try 
     { 
      string userName, domainName; 
      // Get the user token for the specified user, domain, and password using the 
      // unmanaged LogonUser method. 
      // The local machine name can be used for the domain name to impersonate a user on this machine. 
      Console.Write("Enter the name of the domain on which to log on: "); 
      domainName = Console.ReadLine(); 

      Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", domainName); 
      userName = Console.ReadLine(); 

      Console.Write("Enter the password for {0}: ", userName); 

      const int LOGON32_PROVIDER_DEFAULT = 0; 
      //This parameter causes LogonUser to create a primary token. 
      const int LOGON32_LOGON_INTERACTIVE = 2; 

      tokenHandle = IntPtr.Zero; 

      // Call LogonUser to obtain a handle to an access token. 
      bool returnValue = LogonUser(userName, domainName, Console.ReadLine(), 
       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); 
       throw new System.ComponentModel.Win32Exception(ret); 
      } 

      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); 
      WindowsImpersonationContext impersonatedUser = newId.Impersonate(); 

      // Check the identity. 
      Console.WriteLine("After impersonation: " 
       + WindowsIdentity.GetCurrent().Name); 

      // Stop impersonating the user. 
      impersonatedUser.Undo(); 

      // Check the identity. 
      Console.WriteLine("After Undo: " + WindowsIdentity.GetCurrent().Name); 

      // Free the tokens. 
      if (tokenHandle != IntPtr.Zero) 
       CloseHandle(tokenHandle); 

     } 
     catch(Exception ex) 
     { 
      Console.WriteLine("Exception occurred. " + ex.Message); 
     } 

    } 
} 
+0

win32 API 호출없이 수행 할 수 있습니까? – chakrit

+0

@chakrit 예, 이미 사용자 토큰을 가지고 있다면이 페이지의 예제를 따라 할 수 있습니다 : http://msdn.microsoft.com/en-us/library/w070t6ka.aspx – Espo

2

로 가장 스레드 컨텍스트를 변경합니다. ID를 변경하고 별도의 프로세스를 시작하려면 runas 명령을 사용해야합니다.

Keith Brown의 Windows 보안 .NET 개발자 안내서는 모든 보안 시나리오를 설명하는 훌륭한 참고 자료입니다. Online version도 사용할 수 있습니다.

관련 문제