Я хочу проверить набор учетных данных на контроллере домена. например:
Username: STACKOVERFLOW\joel
Password: splotchy
Метод 1. Запрос Active Directory с олицетворением
Многие люди предлагают запросить что-нибудь в Active Directory. Если генерируется исключение, значит, вы знаете, что учетные данные недействительны - как предлагается в этом вопросе о переполнении стека .
Однако у этого подхода есть несколько серьезных недостатков :
Вы не только аутентифицируете учетную запись домена, но также выполняете неявную проверку авторизации. То есть вы читаете свойства из 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.