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.
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