Простой клиент Kerberos в Java?

Приложения, такие как Google Chrome и IE, могут прозрачно обрабатывать аутентификацию Kerberos; Однако я не могу найти "простое" решение Java, чтобы соответствовать этой прозрачности. Все решения, которые я нашел, требуют наличия файла krb5.conf и файла login.conf, которые, как представляется, не требуются ни в одном из перечисленных выше приложений.

Каков наилучший способ создания приложения Java с возможностями SSO Kerberos, которые просто работают?

[обновление]: чтобы быть ясным, мне нужно решение КЛИЕНТА для создания заявок, не проверяя их. Кроме того, кажется, что SPNEGO является протоколом "обертки" по умолчанию, который в конечном итоге будет делегирован Kerberos, но мне нужно иметь возможность обрабатывать и протокол SPNEGO.

9 ответов

Решение

У Oracle есть пример, использующий Java SaslClient. Я не программист на Java, но когда я однажды указал на это кому-то, кто смог, они смогли заставить его работать довольно быстро. Для этого может потребоваться где-то файл "conf" (например, Kerberos использует переменные окружения, часто начиная с KRB5_, чтобы знать, где искать такие файлы). Также обратите внимание, что сам Kerberos не включает какой-либо транспорт - ваше приложение должно знать, как отправлять и получать полезные нагрузки Kerberos так, как ожидает сервер (и это зависит от сервера, с которым вы пытаетесь пройти аутентификацию).

Изменить: вы отредактировали свой вопрос, поэтому вот ссылка, связанная со SPNEGO в Java, которая может быть полезна: http://download.oracle.com/javase/6/docs/technotes/guides/security/jgss/lab/part5.html

Теперь есть простое решение для этого с использованием Apache HTTP Components Client 4.5 или более поздней версии. Это все еще помечено как экспериментальное в 4.5, так что ваш пробег может варьироваться, но это хорошо работает для меня в контексте предприятия.

В дополнение к клиентским jar-файлам HC 4.5 вам потребуется иметь jar-файлы httpclient-win, jna и jna-platform на вашем classpath, как это предусмотрено в http-component-client. Затем вы создаете HC-клиент с поддержкой Kerberos следующим образом:

CloseableHttpClient httpclient = WinHttpClients.createDefault();

Или используя строитель:

HttpClientBuilder clientBuilder = WinHttpClients.custom();

Который затем можно настроить по мере необходимости перед сборкой клиента:

CloseableHttpClient client = clientBuilder.build();

Это решение работает без какой-либо внешней настройки и, самое главное, решает проблему, когда встроенный механизм JRE ломается для пользователей с правами локального администратора в Windows 7+. Это возможно, потому что билет Kerberos извлекается непосредственно из API SSPI через JNA, а не через GSSAPI, предоставленный JRE.

Пример кода от команды http-компонент

Все это стало возможным благодаря хорошей работе Даниэля Дубровкина Тимоти Уолла и Райана МакКинли

Добавление к ответу Дэвида Русселса о специфичной для URL аутентификации Kerberos на основе http:

Причина, по которой ваш код работает, заключается в том, что ваше целевое имя участника-службы (субъект на стороне сервера) настроено с HTTP/serverhostname.realm.com@DOMAIN.COM. В этом случае это будет работать, потому что вы не устанавливаете токен явно. URLConnection внутренне устанавливает токен с этим SPN

1 Выполните шаги (из моего предыдущего ответа), чтобы получить предмет

2 Используйте контекст gss api init sec для генерации токена контекста. Есть множество учебных пособий для этого шага

3 Base 64 кодируют токен

4 Присоедините токен к URL-соединению: -

URL url = new URL("http://myhost/myapp")
HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); = 
urlConn.setRequestProperty("Authorization", "Negotiate " + encodedToken);

5 Выполните привилегированное действие: -

//this internally calls the getInputStream
public class PrivilegedGetInputStream implements PrivilegedExceptionAction<InputStream>

6 Оберните все это в Subject.doAs

//use prev answer instructions to get subject
Subject.doAs(subject, new PrivilegedGetInputStream(urlConnection)

Вам на самом деле не нужно ничего делать. В Java 6 на клиентском компьютере с Windows вы можете сделать это:

new URL("http://myhost/myapp").openStream();

И согласование аутентификации просто работает. По крайней мере, это для меня. И сервер, на котором я тестировал, поддерживает только согласование, а не NTLM-аутентификацию.

Хорошо, если вы хотите избежать использования файла login.conf, вам нужно написать другой код:-

//define your own configuration
import javax.security.auth.login.Configuration;
public class CustomLoginConfiguration extends Configuration

//pass certain parameters to its constructor
//define an config entry
import javax.security.auth.login.AppConfigurationEntry;
private AppConfigurationEntry configEntry;

//define a map of params you wish to pass and fill them up
//the map contains entries similar to one you have in login.conf
Map<String, String> params = new HashMap<String, String>();

//define the configuration
configEntry = new AppConfigurationEntry(
            "com.sun.security.auth.module.Krb5LoginModule",
            AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, params);

//implement getappconfig method
public AppConfigurationEntry[] getAppConfigurationEntry() {
    return new AppConfigurationEntry[] { configEntry };
}

Теперь, когда вы закончили с этим определением, вы можете использовать его, чтобы использовать его для получения билетов из KDC.

//get ticket in login context
LoginContext lc = null;
    lc = new LoginContext("lc", null, callback, new CustomLoginConfiguration(argumentlist));
    lc.login();

Теперь вы можете выбрать тему jaas и выполнить кучу аутентификации.

Если вам нужны дополнительные указатели, просто оставьте комментарий.

Вы можете использовать системные свойства вместо файлов конфигурации, чтобы указать имя хоста KDC и имя службы, но эти вещи (по крайней мере) являются обязательными....

Waffle фактически предоставит вам информацию, необходимую для установки большинства свойств, даже если вы не получите билет. Посмотрите на класс WindowsAuthProviderImpl (файл справки Waffle.chm показывает API).

Я использую JAAS получить билет службы из Active Directory в два этапа:

  1. Используйте Krb5LoginModule, чтобы извлечь кэшированный TGT и добавить его в тему.

  2. Используйте Subject и GSS-API, чтобы получить билет службы из KDC.

В Java Way of Active Directory есть много полезной информации и примеров кода.

Я создал небольшой инструмент для упрощения соединения с httpclient с kerberos, вы можете попробовать его. https://github.com/DovAmir/httpclientAuthHelper

DefaultHttpClient httpclient = new DefaultHttpClient();
AuthUtils.securityLogging(SecurityLogType.KERBEROS,true);
CredentialsUtils.setKerberosCredentials(client, new UsernamePasswordCredentials("xxx", "xxx"), "domain", "kdc");
client.executeMethod(httpget);

Вот хороший пост в блоге о наличии Java-клиента для использования с Kerberos http://sachithdhanushka.blogspot.com/2014/02/kerberos-java-client-configuration.html

Используйте WAFFLE

Другие вопросы по тегам