2011-09-07 34 views
9

Tôi thấy một số hành vi lạ ở đây bằng cách sử dụng PrincipalContext.ValidateCredentials. Thiết lập là hai miền Active Directory trong thiết lập cha/con (vì vậy chúng tôi có tên miền chính company.com và tên miền phụ development.company.com).ValidateCredentials trả về true cho người dùng không xác định?

Khi tôi xác thực bằng chứng xác thực đối với tên miền chính, ValidateCredentials hoạt động như mong đợi, trả về true cho các cặp người dùng/lượt truy cập tốt và giả cho bất kỳ điều gì khác.

Tuy nhiên, nếu tôi xác thực người dùng trong miền phụ, ValidateCredentials sẽ trả về true cho cả tên người dùng/mật khẩu tốt và người dùng không hợp lệ. Nếu tôi cung cấp cho người dùng hợp lệ một mật khẩu không hợp lệ, nó sẽ trả về false một cách chính xác.

Bây giờ tôi đang làm việc xung quanh nó tại thời điểm này bằng cách thực hiện UserPrincipal.FindByIdentity() trước tiên và nếu người dùng tồn tại, sau đó gọi số ValidateCredentials - nhưng tôi muốn hiểu điều gì đang xảy ra.

Một workaround Tôi đã nhìn vào là bằng cách thông qua tên người dùng thông qua như domain\username như MSDN entry for ValidateCredentials states:

Trong mỗi phiên bản của chức năng này, chuỗi userName có thể ở một trong nhiều định dạng khác nhau . Để biết danh sách đầy đủ các loại định dạng có thể chấp nhận được , hãy xem tài liệu ADS_NAME_TYPE_ENUM.

... trong đó tên người dùng này được liệt kê. Nhưng điều này gây ra ValidateCredentials để luôn trở thành sự thật, không có vấn đề gì kết hợp của tên người dùng và mật khẩu tôi vượt qua trong

Mã thích hợp là:

bool authenticated = false; 

// Various options tried for ContextOptions, [etc] inc. explicit username/password to bind to AD with -- no luck. 
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain, null, ContextOptions.Negotiate, null, null)) 
{ 
    log(pc.ConnectedServer + " => " + pc.UserName + " => " + pc.Name + " => " + pc.Container); 
    using (var user = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, username)) 
    { 
     if (user != null) 
     { 
      log(user.DistinguishedName + "; " + user.DisplayName); 
      authenticated = pc.ValidateCredentials(username, password); 
     } else { 
      log("User not found"); 
      // Debug only -- is FindByIdentity() needed. This should always return 
      // false, but doesn't. 
      authenticated = pc.ValidateCredentials(username, password); 
     } 
    } 
} 
return authenticated; 

Bất kỳ và tất cả (sensible) gợi ý đón - Tôi. gãi đầu của tôi về điều này vì nó chỉ đi ngược lại tất cả mong đợi.

Tôi phải thêm: đây là bản thân tôi đang chạy trên máy của tôi, cả hai đều là thành viên của miền chính. Tuy nhiên tôi cũng đã cố gắng chạy nó trong một dấu nhắc lệnh trên máy tính của tôi như là một người sử dụng của các tên miền phụ (runas /user:subdomain\user cmd) với kết quả chính xác giống nhau.

+0

Tôi có hai miền. Tôi có thể sử dụng địa chỉ ip cho miền của mình để gọi xác thực thông tin xác thực và thành công nếu tôi chỉ chuyển tên người dùng hoặc mật khẩu cho người dùng từ một trong hai tên miền. Tôi hơi ngạc nhiên vì tôi không phải cung cấp thêm thông tin này, và một chút bối rối sau đó làm thế nào tôi chắc chắn rằng tôi đang xác nhận đúng người dùng từ đúng tên miền. (Mỗi người có thể nói một thợ rèn không?) – Greg

Trả lời

16

Một số lượng googling sau này (không phải là tôi đã từng vào và ra khỏi google cả ngày cố gắng tìm điều này), tôi đã found the answer.

Nói một cách đơn giản, nếu tài khoản Khách được bật trong miền, ValidateCredentials sẽ trả về TRUE cho người dùng không xác định. Tôi vừa kiểm tra trạng thái của người dùng khách trong development.company.com và chắc chắn rằng tài khoản đã được bật. Nếu tôi đã vô hiệu hóa tài khoản khách, ValidateCredentials trả về false một cách chính xác.

Đây là một bản ghi khá cơ bản, không chắc tôi quan tâm đến hành vi này ... tiếc là nó không được đề cập rõ ràng trên MSDN.

+0

Wow ... đó là một điều dễ dàng mà có thể là một lỗ hổng bảo mật lớn. Cảm ơn câu trả lời! –

+2

Tại sao API của AD phải bị não chết? –

+0

5 năm trước và trường hợp vẫn như cũ. Đã giật mình khi thấy 'principalContext.ValidateCredentials (" blah "," blah ", ContextOptions.Negotiate)' để trả về 'true'. – trailmax

0

Nó có thể được liên quan đến this:

Các ValidateCredentials phương pháp liên kết với máy chủ theo quy định tại các nhà xây dựng . Nếu tham số tên người dùng và mật khẩu là null, thông tin đăng nhập được chỉ định trong hàm tạo được xác thực. Nếu không có thông tin xác thực được chỉ định trong hàm tạo và tên tham số và thông số mật khẩu là rỗng, phương pháp này xác thực thông tin xác thực mặc định cho hiệu trưởng hiện tại.

+0

Không ... khi nó bật ra, tài khoản khách cấp miền đã được bật; nếu tôi vô hiệu hóa nó, ValidateCrendentials làm điều đúng. (Và như là điển hình, sau khi hầu hết các ngày cố gắng để tìm câu trả lời, 20 phút sau khi đăng bài này tôi tìm thấy câu trả lời). –

+0

Luôn luôn là trường hợp :) – TheCodeKing

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