Проверка подлинности Kerberos с помощью SSPI
Примечание: мне удается добиться некоторого прогресса, см. Редактирование моего текущего вопроса, спасибо.
Я хотел бы использовать libcurl в Windows для доступа к веб-сайтам с аутентификацией Kerberos/GSSAPI. Сначала я попытался разобраться с MIT Kerberos, но мне также требуется NTLM-аутентификация с использованием SSPI (libcurl не поддерживает использование обоих из двух разных реализаций). Поэтому я ищу аутентификацию в Kerberos с использованием библиотеки Windows SSPI. Мне удалось скомпилировать libcurl с поддержкой SSPI и SPNEGO.
Теперь моя проблема заключается в том, что мне нужно подключиться к любой предоставленной области с предоставленными учетными данными (это может быть область текущего пользователя или другая). Из того, что я понял, мне нужно вызвать AcquireCredentialsHandle и InitializeSecurityContext из secur32.dll/security.dll, чтобы получить билет Kerberos.
Но каждый раз, когда я пытаюсь заставить это работать, я:
- Не покупайте билеты из DC предоставленных учетных данных / области в кэше SSPI (я использую kerbtray.exe для просмотра записей).
- Должен ли я увидеть тикет в этом кэше при использовании этих методов?
- Используя libcurl после вызова ImpersonateSecurityContext с зацикливанием клиента / сервера InitializeSecurityContext/AcceptSecurityContext и просматривая пакеты в Wireshark, я вижу, что libcurl не использует ни одного из предоставленных учетных данных и вместо этого возвращается к NTLM (что просто вызывает сбой аутентификации)
- Является ли петлевой клиент / сервер правильным поведением (я не смог найти в Интернете ни одного примера другой реализации)?
- Должен ли libcurl использовать олицетворенные учетные данные потока, предполагая, что олицетворение прошло успешно?
- Поддерживает ли libcurl NTLM + Kerberos с помощью SSPI (я даже не уверен в этом...)?
Чтобы облегчить отладку и тестирование, знаете ли вы какой-либо инструмент для добавления записи в кэш SSPI, такой как kinit из библиотеки MIT Kerberos? Я использую Windows Server 2003 Resource Kit Tools, но я не смог найти такой инструмент...
Любая помощь будет принята с благодарностью!
РЕДАКТИРОВАТЬ
Хорошо, я узнал, как сделать то, что я хочу, используя libcurl. Наконец, я предполагал, что мне нужно было заранее поработать с SSPI, но curl правильно это поддерживает.
curl выполнит аутентификацию в области kerberos и сохранит ее в кэше LSA при использовании правильно построенной версии curl с флагами SSPI и SPNEGO.
При использовании curl.exe для тестирования необходимо указать аргумент --negotiate вместе с именем пользователя / паролем. Однако при использовании libcurl просто установите параметр CURLOPT_HTTPAUTH для всего, что содержит CURLAUTH_GSSNEGOTIATE (например, CURLAUTH_ANY). В моих тестах libcurl сделал ожидаемое рукопожатие Kerberos:
- Обратитесь к веб-серверу (web.b.com, где B.COM - это область Kerberos веб-сервера)
- Получен неавторизованный ответ с параметром WWW-Authenticate, установленным на Negotiate
- Libcurl / SSPI отправляет TGS-REQ контроллеру домена (DC) домена текущего пользователя (скажем, A.COM)
- Каким-то образом следующий TGS-REQ отправляется контроллеру домена веб-сервера (B.COM)
- Получил билет Kerberos домена B.COM и запись добавлена в кэш LSA (для просмотра с помощью klist.exe или kerbtray.exe)
- Libcurl отправляет HTTP-запрос на веб-сервер с информацией авторизации (GSS-API)
Однако, и вот моя новая проблема, все это рукопожатие было сделано с текущими зарегистрированными учетными данными, скажем user1@A.COM. Поскольку между A.COM и B.COM существует доверие, и мой пользователь имеет доступ, это работает. Что я хотел бы, чтобы использовать предоставленные учетные данные (user2.B.COM) для входа?
Кроме того, я не совсем уверен, возможно ли добавить запись в кэш LSA другого пользователя, чем тот, который в данный момент зарегистрирован??
Как я могу сделать это, выдав себя за пользователя user2.B.COM таким образом, чтобы libcurl имел доступ к заявке, связанной с этим пользователем, для аутентификации на веб-сервере?
1 ответ
Возможно, это поможет кому-то в будущем, поэтому вот мое решение проблемы, которое я перечислил выше.
Я использовал методы LogonUser и ImpersonateLoggedOnUser для олицетворения потока с указанным пользователем. Используя это, curl использовал кэш LSA, связанный с пользовательской идентификацией потока, и смог получить доступ к веб-серверу, используя эту идентификационную информацию.
В моей настройке я получаю следующие пакеты Kerberos:
- AS-REQ на контроллере домена A.COM с ответом KDC_ERR_WRONG_REALM
- AS-REQ на контроллере домена B.COM с ответом KRB5KDC_ERR_PREAUTH_REQUIRED
- AS-REQ на контроллере домена B.COM
- TGS-REQ на контроллере домена B.COM
- HTTP-запрос с информацией аутентификации GSS-API
Затем я могу сделать любой запрос к веб-серверу на B.COM, если олицетворение действительно.