2010-08-26 23 views
15

Tôi đang cố sử dụng thư viện .NET System.DirectoryServices.AccountManagement để lấy UserPrincipal cho một người dùng Active Directory cụ thể.UserPrincipal.FindByIdentity Permissions

Tôi đã có đoạn mã sau:

PrincipalContext context = new PrincipalContext(ContextType.Domain, "DomainName"); 
userPrincipal = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username); 

Mã này được chạy như một người sử dụng tên miền hợp lệ, nhưng khi tôi thực hiện nó tôi nhận được ngoại lệ sau đây:

System.DirectoryServices. DirectoryServicesCOMException (0x8007052E): Lỗi đăng nhập: tên người dùng không rõ hoặc mật khẩu không đúng.

Điều thú vị là tôi có thể thực hiện cuộc gọi sau đây, sử dụng bối cảnh tương tự, mà không có một vấn đề:

context.ValidateCredentials(username, password, ContextOptions.Negotiate) 

Ý tưởng?

+0

Kiểm tra câu trả lời này: http://stackoverflow.com/questions/1863801/findbyidentity-failing-with-pricipaloperationexception-in-asp-net-webapp/3515280#3515280 –

Trả lời

12

Bạn cần sử dụng công cụ xây dựng PrincipalContext có tên người dùng và mật khẩu.

Lý do xác thực tác phẩm là do sử dụng thông tin đăng nhập được cung cấp để liên kết với thư mục.

+0

Điều này không có nhiều ý nghĩa với tôi. Bạn đang nói rằng cuộc gọi ValidateCredentials sử dụng thông tin xác thực danh tính hiện tại, nhưng cuộc gọi UserPrincipal.FindByIdentity, chấp nhận ngữ cảnh được đề cập, phải không? Nếu đó là trường hợp, làm cách nào để tôi sử dụng danh tính hiện tại (như trong danh tính của chủ đề) để thực hiện cuộc gọi? Tôi không có tên người dùng hoặc mật khẩu để vượt qua, vì đây là một ứng dụng đang chạy khi thiết lập tài khoản dịch vụ vào lúc cài đặt. Tôi không thể lưu trữ các thông tin đăng nhập này ở bất kỳ đâu. – RMD

+0

Tôi nghĩ bạn hiểu lầm, ValidateCredentials sử dụng thông tin đăng nhập được cung cấp trong danh sách tham số cho ValidateCredentials - Context bạn đã xác định không có thông tin xác thực nào liên quan đến nó bên cạnh các thông tin của chuỗi hiện tại. Tôi nghi ngờ vấn đề của bạn là trong cấu hình/triển khai của máy chủ. Đảm bảo rằng tài khoản đang chạy dịch vụ đã được ủy nhiệm trong miền. – Nate

+0

Vâng, tôi hiểu lầm. Người dùng của luồng hiện tại chắc chắn là người dùng miền hợp lệ. Khi bạn nói "được ủy nhiệm trong miền", bạn có ý nghĩa gì? – RMD

3

Có vẻ như bạn có thông tin đăng nhập mạng được lưu trữ. Trong Windows, bạn có thể chỉ định sử dụng thông tin xác thực mạng khác khi cố gắng truy cập tài nguyên mạng. Tôi có thể tái tạo chính xác cùng một vấn đề như bạn đang thấy bằng cách thiết lập thông tin xác thực mạng sai.

Giả sử tên miền của bạn được gọi là yourdomain.com, bạn có thể yêu cầu Windows luôn sử dụng tên người dùng và mật khẩu cụ thể bất cứ khi nào nó nói với bất kỳ máy tính nào có đủ yourdomain.com.

=== của Windows 7/2008 ===

  1. Launch các "Crendentail Manager".
  2. Dưới phần thông tin Windows, bấm Add a Windows credentials
  3. Trong địa chỉ mạng, đưa vào *.yourdomain.com
  4. Trong tên truy cập và mật khẩu, đưa vào tên người dùng hoặc mật khẩu sai sai

=== Windows XP/2000/2003 ===

  1. Bấm Start và Run
  2. Gõ vào control keymgr.dll
  3. Bấm nút Add vào "lưu trữ tên người dùng và mật khẩu" hộp thoại
  4. Trong hộp máy chủ văn bản, đưa vào *.yourdomain.com
  5. Trong username và password, đưa vào tên người dùng sai hoặc sai mật khẩu

Nếu đây thực sự là các vấn đề mà bạn đang phải đối mặt, sửa chữa dễ dàng là để loại bỏ các mật khẩu được lưu trữ.

Tại sao context.ValidateCredentials (tên người dùng, mật khẩu, ContextOptions.Negotiate) hoạt động?Đơn giản là vì bạn đang khởi tạo xác thực Kerberos/NTLM khác vì bạn cung cấp lại uernamepassword. Dưới mui xe, nếu Kerberos được chọn, nó sẽ gửi bộ điều khiển miền tên người dùng và mật khẩu được cung cấp và trao đổi cho một vé Kerberos TGT. Sau đó, máy của bạn nhận được một vé dịch vụ trên máy chủ LDAP bằng cách sử dụng vé TGT này. Sau đó, máy của bạn sẽ gửi vé dịch vụ này đến máy chủ LDAP. Lưu ý rằng vé dịch vụ này sẽ không được giữ lại trong phiên đăng nhập hiện tại.

Tại sao UserPrincipal.FindByIdentity không hoạt động? Nếu bạn không có bất kỳ mật khẩu được lưu trữ nào, thông thường nó sẽ hoạt động vì Windows sẽ chỉ sử dụng vé TGT của người dùng đăng nhập hiện tại để đổi lấy vé dịch vụ máy chủ LDAP. Không có quy trình xác thực tên người dùng/mật khẩu nào có liên quan. Tuy nhiên, nếu bạn có một mật khẩu tên người dùng xấu, Windows sẽ nghĩ rằng nó không nên sử dụng vé đăng nhập TGT của người dùng đăng nhập hiện tại. Thay vào đó, nó sẽ nhận được một vé TGT mới bằng cách sử dụng mật khẩu mạng được lưu trữ. Đó là lý do bạn nhìn thấy System.DirectoryServices.DirectoryServicesCOMException (0x8007052E): Logon failure: unknown user name or bad password.

+0

Thú vị. Mã này chạy từ ngữ cảnh của một ứng dụng ASP.NET, vì vậy tôi sẽ không nghĩ rằng mật khẩu được lưu trữ sẽ tạo ra sự khác biệt. Tôi sẽ kiểm tra xem bạn có đúng không. – RMD

+0

@RMD Ah, bạn đã bỏ lỡ thông tin này. Bạn có đang sử dụng Xác thực Windows không? Hay bạn chỉ đơn giản là sử dụng tài khoản dịch vụ địa phương để truy cập vào AD? –

+0

Như tôi đã nói trong bài đăng gốc của mình: "Mã này đang chạy dưới dạng người dùng tên miền hợp lệ". – RMD

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