Tôi muốn xác thực một bộ thông tin xác thực đối với bộ điều khiển miền. ví dụ:
Username: STACKOVERFLOW\joel
Password: splotchy
Phương pháp 1. Truy vấn Active Directory với Mạo danh
Rất nhiều người đề nghị truy vấn Active Directory cho một cái gì đó. Nếu một ngoại lệ được đưa ra, thì bạn biết thông tin đăng nhập không hợp lệ - như được đề xuất trong câu hỏi stackoverflow này .
Tuy nhiên, có một số nhược điểm nghiêm trọng đối với phương pháp này :
Bạn không chỉ xác thực tài khoản miền mà còn thực hiện kiểm tra ủy quyền ngầm. Đó là, bạn đang đọc các thuộc tính từ AD bằng cách sử dụng mã thông báo mạo danh. Điều gì xảy ra nếu tài khoản hợp lệ khác không có quyền đọc từ AD? Theo mặc định, tất cả người dùng đều có quyền truy cập đọc, nhưng chính sách miền có thể được đặt để tắt quyền truy cập cho các tài khoản bị hạn chế (và hoặc nhóm).
Liên kết với AD có chi phí nghiêm trọng, bộ đệm lược đồ AD phải được tải tại máy khách (bộ đệm ADSI trong nhà cung cấp ADSI được sử dụng bởi DirectoryService). Đây là cả mạng và máy chủ AD, tiêu tốn tài nguyên - và quá tốn kém cho một thao tác đơn giản như xác thực tài khoản người dùng.
Bạn đang dựa vào một lỗi ngoại lệ cho một trường hợp không đặc biệt và giả sử điều đó có nghĩa là tên người dùng và mật khẩu không hợp lệ. Các vấn đề khác (ví dụ như lỗi mạng, lỗi kết nối AD, lỗi cấp phát bộ nhớ, v.v.) sau đó được hiểu sai là lỗi xác thực.
Phương pháp 2. LogonUser Win32 API
Những người khác đã đề xuất sử dụng LogonUser()
chức năng API. Điều này nghe có vẻ hay, nhưng thật không may, người dùng gọi đôi khi cần một sự cho phép thường chỉ được cấp cho chính hệ điều hành:
Quá trình gọi LogonUser yêu cầu đặc quyền SE_TCB_NAME. Nếu quá trình gọi không có đặc quyền này, LogonUser sẽ thất bại và GetLastError trả về ERROR_PRIVILEGE_NOT_HELD.
Trong một số trường hợp, quy trình gọi LogonUser cũng phải được bật đặc quyền SE_CHANGE_NOTIFY_NAME; mặt khác, LogonUser không thành công và GetLastError trả về ERROR_ACCESS_DENIED. Đặc quyền này không bắt buộc đối với tài khoản hệ thống cục bộ hoặc tài khoản là thành viên của nhóm quản trị viên. Theo mặc định, SE_CHANGE_NOTIFY_NAME được bật cho tất cả người dùng, nhưng một số quản trị viên có thể vô hiệu hóa nó cho mọi người.
Trao đặc quyền " Hoạt động như một phần của hệ điều hành " không phải là điều bạn muốn làm willy-nilly - như Microsoft đã chỉ ra trong một bài viết cơ sở tri thức :
... Quá trình đang gọi LogonUser phải có đặc quyền SE_TCB_NAME (trong Trình quản lý người dùng, đây là quyền " Hoạt động như một phần của Hệ điều hành "). Đặc quyền SE_TCB_NAME rất mạnh mẽ và không nên được cấp cho bất kỳ người dùng tùy ý nào để họ có thể chạy một ứng dụng cần xác thực thông tin đăng nhập.
Ngoài ra, một cuộc gọi đến LogonUser()
sẽ thất bại nếu mật khẩu trống được chỉ định.
Cách thích hợp để xác thực một bộ thông tin xác thực tên miền là gì?
Tôi tình cờ gọi từ mã được quản lý, nhưng đây là một câu hỏi chung của Windows. Có thể giả định rằng các khách hàng đã cài đặt .NET Framework 2.0.
Bạn đọc cần lưu ý rằng kể từ Windows XP, LogonUser không còn yêu cầu SE_TCB_NAME (trừ khi bạn đang đăng nhập vào tài khoản Passport).
– Tạ Khánh Vy 05:42:49 06/08/2014