Java автоматически использует Kerberos ticketCache, когда не следует?
У нас есть серверное приложение, которое может общаться с внешними сервисами. От нашей конфигурации зависит, проводим ли мы проверку подлинности на основе этих служб с учетными данными пользователя, который нас вызвал, с предварительно настроенными учетными данными или нет вообще.
Внешние сервисы могут использовать HTTP-аутентификацию. Для наших пользовательских запросов HTTP/WebDAV мы используем Apache HttpClient, где у нас есть обработка учетных данных под нашим собственным контролем. Но для вызовов JAX-WS (или простых URL-адресов HTTP, вызываемых сторонними библиотеками), HttpUrlConnection Java обрабатывает саму аутентификацию. Здесь вещи становятся странными.
Якобы Java всегда пытается использовать учетные данные Kerberos из текущей темы для переговоров. Это нормально, и работает. Он также может использовать кеш билетов (то есть сеанс kinit или системный сеанс, если он доступен), НО, если я правильно прочитал документацию (*), он должен делать это только при двух условиях:
*) https://docs.oracle.com/javase/8/docs/technotes/guides/security/jgss/lab/part6.html
- javax.security.auth.useSubjectCredentialsOnly явно установлен в false
- Была предоставлена пользовательская конфигурация JAAS, которая явно устанавливает для useTicketCache значение true
Это не то, что происходит. В наших воспроизводимых тестах по умолчанию всегда используются системные учетные данные, если тема пуста. Хуже того, явные настройки useSubjectCredentialsOnly в значение true (которое должно быть по умолчанию) не изменяют это поведение. Единственный обходной путь, который мы нашли до настоящего времени, - это явное предоставление пользовательской конфигурации JAAS, которая устанавливает для useTicketCache значение false (что опять-таки должно быть значением по умолчанию).
Отладка в Krb5LoginModule показывает, что, если мы не настроим этот обходной путь, модуль входа в систему на самом деле вызывается с useTicketCache = true.
Мы можем воспроизвести это на всех наших системах Windows. Кажется, Linux может вести себя нормально, но я не смог проверить это подробно (из-за проблем с доменом).
Я неправильно читаю документацию? Или есть ошибка в реализации Java? Или наши системы Windows шаткие?
Кажется, очень не идеально, что мы должны указывать нашим клиентам всегда настраивать обходной путь, чтобы Java не тайно вызывал удаленные сервисы с учетными данными пользователя сервиса, а не пользователя, отправившего запрос в наш сервис.
1 ответ
По крайней мере, в коде Java 8 u 131 в Linux, который я только что отлаживал, функция sun.security.jgss.GSSUtil.useSubjectCredsOnly(вызывающая сторона GSSCaller) жестко запрограммирована на возврат false, если вызывающая сторона является экземпляром HttpCaller.
Для вызывающих абонентов других типов проверяется свойство javax.security.auth.useSubjectCredsOnly.