2010-05-11 5 views
6

उपयोगकर्ता नाम और पासवर्ड को देखते हुए मैं उस उपयोगकर्ता का प्रतिरूपण कैसे करता हूं और उस उपयोगकर्ता के रूप में कुछ कोड चलाता हूं।प्रबंधित कोड में किसी उपयोगकर्ता का प्रतिरूपण कैसे करें?

और द्वारा प्रबंधित मैं pinvokes या dllimports

उत्तर

13

यह आवरण वर्ग है हमने बनाया है कि कई अलग-अलग विंडोज प्लेटफ़ॉर्म पर काम किया है:

public class Impersonator 
{ 
    // constants from winbase.h 
    public const int LOGON32_LOGON_INTERACTIVE = 2; 
    public const int LOGON32_LOGON_NETWORK = 3; 
    public const int LOGON32_LOGON_BATCH = 4; 
    public const int LOGON32_LOGON_SERVICE = 5; 
    public const int LOGON32_LOGON_UNLOCK = 7; 
    public const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8; 
    public const int LOGON32_LOGON_NEW_CREDENTIALS = 9; 

    public const int LOGON32_PROVIDER_DEFAULT = 0; 
    public const int LOGON32_PROVIDER_WINNT35 = 1; 
    public const int LOGON32_PROVIDER_WINNT40 = 2; 
    public const int LOGON32_PROVIDER_WINNT50 = 3; 

    [DllImport("advapi32.dll", SetLastError=true)] 
    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); 

    public static WindowsImpersonationContext LogOn(string userName, string password) 
    { 
     return LogOn(userName, password, ""); 
    } 

    public static WindowsImpersonationContext LogOn(string userName, string password, string domain) 
    { 
     WindowsIdentity tempWindowsIdentity; 
     WindowsImpersonationContext impersonationContext; 
     IntPtr token = IntPtr.Zero; 
     IntPtr tokenDuplicate = IntPtr.Zero; 

     if(RevertToSelf()) 
     { 
      if (LogonUserA(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) 
        { 
         CloseHandle(token); 
         CloseHandle(tokenDuplicate); 
         return impersonationContext; 
        } 
       } 
      } 
      else 
      { 
       var win32 = new Win32Exception(Marshal.GetLastWin32Error()); 
       //throw new Exception(string.Format("{0}, Domain:{1}, User:{2}, Password:{3}", 
       // win32.Message, domain, userName, password)); 
       throw new Exception(win32.Message); 
      } 
     } 
     if(token!= IntPtr.Zero) 
      CloseHandle(token); 
     if(tokenDuplicate!=IntPtr.Zero) 
      CloseHandle(tokenDuplicate); 
     return null; // Failed to impersonate 
    } 

    public static bool LogOff(WindowsImpersonationContext context) 
    { 
     bool result = false; 
     try 
     { 
      if (context != null) 
      { 
       context.Undo(); 
       result = true; 
      } 
     } 
     catch 
     { 
      result = false; 
     } 
     return result; 
    } 
} 
+0

महान जॉन काम किया। धन्यवाद। – GR7

+0

आपका स्वागत है, silverCORE –

+0

आपको LOGON32_PROVIDER_x मान कहां मिले? –

1

वहाँ एक महान जवाब here के साथ एक समान सवाल है बिना मतलब है।

कुछ और जानकारी के लिए WindowsImpersonationContext पर एक नज़र डालें

+0

उत्सुक था अगर इसे किसी भी dllimports – Simon

+2

के बिना किया जा सकता है यदि यह एक एएसपी.नेट वेबसाइट है, तो हाँ इसे 'वेब पर' प्रतिरूपण /> 'तत्व सेट करके किया जा सकता है .config'। । नहीं तो आप आयात :( – Codesleuth

+0

@Simon का उपयोग करना होगा:। प्रतिरूपण प्रतिष्ठानों के दौरान या "के रूप में" इस तरह के एक प्रशासक के रूप में किसी और को, एक आवेदन को चलाने के लिए भी उपयोगी है – AMissico

0

Is it possible to safely get a SecureString value from VB .NET? की ImpersonationHelper देखें (भी वहाँ एक और महान कोड नमूना है)। कोड उत्पादन तैयार और मजबूत है।

यह IDisposable का समर्थन करता है, एक RunAs विधि (जो अमूल्य है), पासवर्ड SecureString के रूप में नियंत्रित किया जाता है, और अन्य छोटी सहायक उपहार में शामिल है। मैं भी दोनों ImpersonationHelper वर्ग समस्या निवारण के लिए अत्यंत उपयोगी है के साथ के लिए परीक्षण कोड प्रदान की है, और उनके SecureString extenstion तरीकों कि काम में आते हैं।

2

मैं दो सरल तरीके के लिए नीचे उबला हुआ है:

public bool ImpersonateValidUser(String userName, String domain, String password) 
public void UndoImpersonation() 

आप प्रतिलिपि directlyh कर सकते हैं/नीचे वर्ग पेस्ट और अपनी परियोजना में इसका इस्तेमाल करते हैं:

class 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); 

     public const int LOGON32_LOGON_NEW_CREDENTIALS = 9; 
     public const int LOGON32_LOGON_INTERACTIVE = 2; 
     public const int LOGON32_PROVIDER_DEFAULT = 0; 
     public const int LOGON32_PROVIDER_WINNT50 = 3; 
     WindowsImpersonationContext impersonationContext; 

     public bool ImpersonateValidUser(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_NEW_CREDENTIALS, 
        LOGON32_PROVIDER_WINNT50, 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; 
     } 

     public void UndoImpersonation() 
     { 
      impersonationContext.Undo(); 
     } 
    } 
+0

ज़रूर, इसे नीचे दो तरीकों के लिए फोड़े फिर भी, अपने कोड इसमें कोई त्रुटि नहीं है, और यदि कोई त्रुटि उत्पन्न होती है, तो इसे बनाए गए हैंडल को रिहा नहीं करता है। – AMissico

2

मेरे द्वारा देखे गए सभी उदाहरण टी में विफल इस तथ्य को ध्यान में रखते हुए कि लॉगऑन प्रकार एक आकार नहीं है, सभी समाधान फिट बैठता है।

उदाहरण के लिए यह केवल काम करेंगे, तो उपयोगकर्ता आपके नाम से कार्य कर रहे हैं लक्ष्य प्रणाली के लिए लॉगऑन करने की अनुमति है। दूरस्थ SQL सर्वर बॉक्स तक पहुंचने पर हमेशा ऐसा नहीं होता है। LOGON32_LOGON_INTERACTIVE

NetworkClearText केवल एक ही है कि SQL सर्वर कनेक्शन के साथ उपयोग के लिए लगातार काम करता है। - कोई स्पष्ट पाठ का मतलब यह नहीं है कि यह असुरक्षित तरीके से प्रमाण-पत्र पास कर रहा है।

जब एक कार्यसमूह पर और आप एक डोमेन उपयोगकर्ता NewCredentials का रूप धारण करने की जरूरत है एक है कि काम करता है। (एसक्यूएल सर्वर कनेक्शन के साथ परीक्षण नहीं किया गया)