2012-01-22 58 views
7

我模擬用戶帳戶成功,但我無法使用模擬帳戶綁定到AD並拉下DirectoryEntry模擬和DirectoryEntry

下面的代碼輸出:

  • 模擬之前我:DOMAIN \用戶
  • 模擬後我:DOMAIN \ ADMIN
  • 錯誤:C:\用戶\用戶\ ADSI_Impersonation \ BIN \調試\ ADSI_Impersonation.exe SAM帳戶名:

我的問題似乎類似於:

How to use the System.DirectoryServices namespace in ASP.NET

我正在獲取主令牌。我知道我需要使用委託在遠程計算機上使用模擬令牌。我確認該帳戶未勾選「帳戶敏感且無法委託」。我也證實了本地組策略和域的組策略不會阻止代表團:

計算機配置\ Windows設置\安全設置\本地策略\用戶權限分配\

我缺少什麼?

謝謝!

using System; 
using System.DirectoryServices; 
using System.Security; 
using System.Security.Principal; 
using System.Runtime.InteropServices; 
using Microsoft.Win32.SafeHandles; 
using System.Runtime.ConstrainedExecution; 

namespace ADSI_Impersonation 
{ 
    class Program 
    { 
     [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
     public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, 
      int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken); 

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

     static void Main(string[] args) 
     { 
      const int LOGON32_PROVIDER_DEFAULT = 0; 
      const int LOGON32_LOGON_INTERACTIVE = 2; 

      string userName = "[email protected]"; 
      string password = "password"; 

      Console.WriteLine("Before impersonation I am: " + WindowsIdentity.GetCurrent().Name); 

      SafeTokenHandle safeTokenHandle; 

      try 
      { 
       bool returnValue = LogonUser(userName, null, password, 
        LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, 
        out safeTokenHandle); 

       if (returnValue) 
       { 
        WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle()); 
        WindowsImpersonationContext impersonatedUser = newId.Impersonate(); 
       } 
       else 
       { 
        Console.WriteLine("Unable to create impersonatedUser."); 
        return; 
       } 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Authentication error.\r\n" + e.Message); 
      } 

      Console.WriteLine("After impersonation I am: " + WindowsIdentity.GetCurrent().Name); 

      string OU = "LDAP://dc=domain,dc=com"; 
      DirectoryEntry entry = new DirectoryEntry(OU); 
      entry.AuthenticationType = AuthenticationTypes.Secure; 

      DirectorySearcher mySearcher = new DirectorySearcher(); 
      mySearcher.SearchRoot = entry; 
      mySearcher.SearchScope = System.DirectoryServices.SearchScope.Subtree; 
      mySearcher.PropertiesToLoad.Add("cn"); 
      mySearcher.PropertiesToLoad.Add("samaccountname"); 

      string cn = "fistname mi. lastname"; 
      string samaccountname = ""; 

      try 
      { 
       // Create the LDAP query and send the request 
       mySearcher.Filter = "(cn=" + cn + ")"; 

       SearchResultCollection searchresultcollection = mySearcher.FindAll(); 

       DirectoryEntry ADentry = searchresultcollection[0].GetDirectoryEntry(); 

       Console.WriteLine("samaccountname: " + ADentry.Properties["samaccountname"].Value.ToString()); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Error: " + e.Message); 
      } 

      Console.WriteLine("samaccountname: " + samaccountname); 
      Console.ReadLine(); 
     } 
    } 

    public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid 
    { 
     private SafeTokenHandle() 
      : base(true) 
     { 
     } 

     [DllImport("kernel32.dll")] 
     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
     [SuppressUnmanagedCodeSecurity] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     private static extern bool CloseHandle(IntPtr handle); 

     protected override bool ReleaseHandle() 
     { 
      return CloseHandle(handle); 
     } 
    } 
} 

回答

1

許多.NET API不會考慮手動模擬,比如您注意到的LDAP查詢。因此,你需要使用的DirectoryEntry代替超載構造,

http://msdn.microsoft.com/en-us/library/bw8k1as4.aspx

http://msdn.microsoft.com/en-us/library/wh2h7eed.aspx

+0

謝謝您確認這是唯一的方法。我想因爲我將有用戶的用戶名/密碼沒有理由不起作用。 –

+0

@Lex李我問一個相關的問題,你會請檢查它:http://stackoverflow.com/questions/18842970/asp-net-imperonate-in-netframework-2-vs-netframework-4 –

0

錯誤(0X80004005):未指定的錯誤

我已經連接到遠程Windows中的一些問題,通過身份驗證錯誤錯誤(0x80004005):未指定的錯誤。我解決如下:

//Define path 
//This path uses the full path of user authentication 
String path = string.Format("WinNT://{0}/{1},user", server_address, username); 
DirectoryEntry deBase = null; 
try 
{ 
    //Try to connect with secure connection 
    deBase = new DirectoryEntry(path, username, _passwd, AuthenticationTypes.Secure); 

    //Connection test 
    //After test define the deBase with the parent of user (root container) 
    object nativeObject = deBase.NativeObject; 
    deBase = deBase.Parent; 

} 
catch (Exception ex) 
{ 
    //If an error occurred try without Secure Connection 
    try 
    { 
     deBase = new DirectoryEntry(path, username, _passwd); 

     //Connection test 
     //After test define the deBase with the parent of user (root container) 
     object nativeObject = deBase.NativeObject; 
     deBase = deBase.Parent; 
     nativeObject = deBase.NativeObject; 

    } 
    catch (Exception ex2) 
    { 
     //If an error occurred throw the error 
     throw ex2; 
    } 
} 

希望有所幫助。 Helvio Junior www.helviojunior.com.br