2009-10-15 24 views
8

Microsoft có mục đích chung KB bài viết (Q316748) mô tả cách xác thực đối với Active Directory bằng cách sử dụng đối tượng DirectoryEntry. Trong ví dụ của mình, họ tạo ra một giá trị tên bằng cách ghép tên miền và tên người dùng sang định dạng NetBIOS chuẩn ("domain \ username") và đi qua đó như là một tham số để các nhà xây dựng vào thư mục:System.DirectoryServices.DirectoryEntry có chứa một hàm tạo thực sự sử dụng "domain username" với Ldap không?

string domainAndUsername = domain + @"\" + username; 
DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd); 

Nó gần đây đã đến chúng tôi chú ý rằng phần tên miền của tên người dùng đã bị bỏ qua hoàn toàn và trong nhiều môi trường, tôi đã xác nhận hành vi này. Tên người dùng và mật khẩu trên thực tế đang được sử dụng, vì xác thực không thành công khi chúng không hợp lệ, nhưng bất kỳ giá trị tùy ý nào cũng có thể được cung cấp cho tên miền và xác thực. Trong nháy mắt tôi muốn lý thuyết định dạng này hoạt động cho WinNT dựa trên truy cập thư mục nhưng phần tên miền được bỏ qua cho LDAP.

Kiểm tra trên google cho thấy nhiều ví dụ LDAP chuyển giá trị "tên miền \ tên người dùng" đến đối tượng DirectoryEntry vì vậy tôi đã hoặc đang làm rối loạn cấu hình của mình hoặc có nhiều người nhầm lẫn với bài viết KB. Bất cứ ai có thể xác nhận đây là hành vi dự kiến ​​hoặc đề nghị một cách để chấp nhận "tên miền \ tên người dùng" giá trị và xác thực đối với Active Directory với họ?

Cảm ơn,

Trả lời

18

Câu trả lời ngắn: Khi path tham số của các nhà xây dựng DirectoryEntry chứa một tên miền hợp lệ đối tượng DirectoryEntry sẽ (sau khi một tìm kiếm không thành công cho các tên miền không hợp lệ trong Forrest) cố gắng một mùa thu trở lại bằng cách thả một phần lĩnh vực tham số username và thử kết nối bằng tên người dùng thuần túy (sAMAccountName).

Câu trả lời dài: Nếu tên miền được quy định trong tham số username không hợp lệ nhưng người dùng tồn tại trong lĩnh vực quy định tại các path tham số người dùng sẽ được chứng thực (thông qua việc sử dụng dự phòng). Tuy nhiên, nếu người dùng tồn tại trong một tên miền khác trong forrest so với một miền được chỉ định trong xác thực thông số path sẽ chỉ thành công khi phần tên miền của thông số username được bao gồm và chính xác.

Có bốn cách khác nhau để xác định các tham số tên khi giao dịch với DirectoryEntry-đối tượng:

  • Distinguished Name (CN = Username, CN = Users, DC = tên miền, DC = local)
  • NT Tên tài khoản (domain \ username)
  • Plain tài khoản Tên/sAMAccountName (username)
  • tài chính Tên (thường [email protected])

Hãy để tôi minh họa bằng một ví dụ:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using System.DirectoryServices; 

namespace DirectoryTest 
{ 
    class Program 
    { 

    private static Int32 counter = 1; 

    static void Main(string[] args) 
    { 
     TestConnection(); 
    } 

    private static void TestConnection() 
    { 
     String domainOne = "LDAP://DC=domain,DC=one"; 
     String domainOneName = "DOMAINONE"; 
     String domainOneUser = "onetest"; 
     String domainOnePass = "testingONE!"; 

     String domainTwo = "LDAP://DC=domain,DC=two"; 
     String domainTwoName = "DOMAINTWO"; 
     String domainTwoUser = "twotest"; 
     String domainTwoPass = "testingTWO!"; 

     String invalidDomain = "INVALIDDOMAIN"; 

     // 1) This works because it's the correct NT Account Name in the same domain: 
     Connect(domainOne, domainOneName + "\\" + domainOneUser, domainOnePass); 

     // 2) This works because username can be supplied without the domain part 
     // (plain username = sAMAccountName): 
     Connect(domainOne, domainOneUser, domainOnePass); 

     // 3) This works because there's a fall back in DirectoryEntry to drop the domain part 
     // and attempt connection using the plain username (sAMAccountName) in (in this case) 
     // the forrest root domain: 
     Connect(domainOne, invalidDomain + "\\" + domainOneUser, domainOnePass); 

     // 4) This works because the forrest is searched for a domain matching domainTwoName: 
     Connect(domainOne, domainTwoName + "\\" + domainTwoUser, domainTwoPass); 

     // 5) This fails because domainTwoUser is not in the forrest root (domainOne) 
     // and because no domain was specified other domains are not searched: 
     Connect(domainOne, domainTwoUser, domainTwoPass); 

     // 6) This fails as well because the fallback of dropping the domain name and using 
     // the plain username fails (there's no domainTwoUser in domainOne): 
     Connect(domainOne, invalidDomain + "\\" + domainTwoUser, domainTwoPass); 

     // 7) This fails because there's no domainTwoUser in domainOneName: 
     Connect(domainOne, domainOneName + "\\" + domainTwoUser, domainTwoPass); 

     // 8) This works because there's a domainTwoUser in domainTwoName: 
     Connect(domainTwo, domainTwoName + "\\" + domainTwoUser, domainTwoPass); 

     // 9) This works because of the fallback to using plain username when connecting 
     // to domainTwo with an invalid domain name but using domainTwoUser/Pass: 
     Connect(domainTwo, invalidDomain + "\\" + domainTwoUser, domainTwoPass); 
    } 

    private static void Connect(String path, String username, String password) 
    { 
     Console.WriteLine(
     "{0}) Path: {1} User: {2} Pass: {3}", 
     counter, path, username, password); 
     DirectoryEntry de = new DirectoryEntry(path, username, password); 
     try 
     { 
     de.RefreshCache(); 
     Console.WriteLine("{0} = {1}", username, "Autenticated"); 
     } 
     catch (Exception ex) 
     { 
     Console.WriteLine("{0} ({1})", ex.Message, username); 
     } 
     Console.WriteLine(); 
     counter++; 
    } 
    } 
} 

Trong ví dụ trên domain.one là tên miền gốc Forrest và domain.two là trong rừng giống như domain.one (nhưng một cây khác nhau một cách tự nhiên).

Vì vậy, để trả lời câu hỏi của bạn: Xác thực sẽ luôn thất bại nếu người dùng không nằm trong miền mà chúng tôi đang kết nối và không có hoặc tên miền không hợp lệ được chỉ định trong tham số username.

+0

Cảm ơn người đàn ông, đó là một câu trả lời chi tiết đáng kinh ngạc và tôi đánh giá cao sự rõ ràng –

+0

bạn đã đề cập đến trường hợp "Tên người dùng chính" trường hợp ([email protected] như định dạng), nhưng không có trường hợp thử nghiệm cho điều đó. nó sẽ hoạt động theo cùng một cách, do đó, "@ domain.local" sẽ, khi không hợp lệ, gây ra một dự phòng trong trường hợp 3) và 9)? – dlatikay

0

Tôi có hai ứng dụng mà sử dụng DirectoryEntry(_path, domainAndUsername, pwd); constructor và tôi không có bất kỳ vấn đề xác thực. Mỗi ứng dụng được cài đặt trên một khách hàng khác nhau, cả hai đều có cấu trúc miền rất (rất lớn).

+0

Hmm và phần tên miền của thông tin đăng nhập được sử dụng và bạn đang kết nối qua LDAP? Tôi không có vấn đề xác thực chính xác, vì nó xác thực thành công trong mọi trường hợp, nhưng nó bỏ qua phần tên miền. Nếu bạn tiền tố có miền không hợp lệ thì auth có bị lỗi không? –

+0

Tôi không thể kiểm tra nó ngay bây giờ, nhưng tôi sẽ làm vào ngày mai và đăng kết quả ở đây –

Các vấn đề liên quan