Я хочу перевірити набір облікових даних проти контролера домену. наприклад:
Username: STACKOVERFLOW\joel
Password: splotchy
Спосіб 1. Запит Active Directory з видаванням себе за іншу особу
Багато людей пропонують щось запитати в Active Directory. Якщо видається виняток, ви знаєте, що облікові дані не є дійсними - як пропонується у цьому запитанні про stackoverflow .
Однак у цього підходу є кілька серйозних недоліків :
Ви не тільки аутентифікуєте обліковий запис домену, але й виконуєте неявну перевірку авторизації. Тобто ви зчитуєте властивості з AD, використовуючи маркер уособлення. Що робити, якщо дійсний інакше рахунок не має права читати з AD? За замовчуванням усі користувачі мають доступ для читання, але політики домену можуть бути встановлені для вимкнення дозволів на доступ для обмежених облікових записів (та або груп).
Прив'язка до AD має серйозні накладні витрати, кеш схеми AD повинен бути завантажений у клієнта (кеш ADSI у постачальнику ADSI, який використовується DirectoryServices). Це і мережа, і сервер AD, що вимагає ресурсів - і є занадто дорогим для такої простої операції, як аутентифікація облікового запису користувача.
Ви покладаєтесь на помилку винятку для не виняткових випадків і припускаєте, що це означає недійсні ім’я користувача та пароль. Інші проблеми (наприклад, збій мережі, збій підключення AD, помилка виділення пам'яті тощо) потім трактуються неправильно як збій автентифікації.
Спосіб 2. LogonUser Win32 API
Інші пропонують використовувати функцію LogonUser()
API. Це звучить приємно, але, на жаль, користувачеві, що телефонує, іноді потрібен дозвіл, який зазвичай надається лише самій операційній системі:
Процес виклику LogonUser вимагає привілею SE_TCB_NAME. Якщо процес виклику не має цієї привілеї, LogonUser не працює, а GetLastError повертає ERROR_PRIVILEGE_NOT_HELD.
У деяких випадках процес, який викликає LogonUser, також повинен мати ввімкнену привілею SE_CHANGE_NOTIFY_NAME; в іншому випадку LogonUser виходить з ладу, а GetLastError повертає ERROR_ACCESS_DENIED. Ця привілея не потрібна для облікового запису локальної системи або облікових записів, які є членами групи адміністраторів. За замовчуванням SE_CHANGE_NOTIFY_NAME увімкнено для всіх користувачів, але деякі адміністратори можуть вимкнути його для всіх.
Роздавати привілей " Закон як частина операційної системи " - це не те, що ви хочете робити волею-неволею - як зазначає Microsoft у статті бази знань :
... процес, який викликає LogonUser, повинен мати привілей SE_TCB_NAME (у Менеджері користувачів це право « Діяти як частина операційної системи »). Привілей SE_TCB_NAME дуже потужний і не повинен надаватися будь-якому довільному користувачеві лише для того, щоб він міг запустити програму, яка повинна перевірити облікові дані.
Крім того, виклик до LogonUser()
не вдасться, якщо вказано порожній пароль.
Який правильний спосіб автентифікації набору облікових даних домену?
Я випадково телефоную з керованого коду, але це загальне питання для Windows. Можна припустити, що у клієнтів встановлено .NET Framework 2.0.