Недавно понадобилось мне получить Kerberos токен в джаве. До сих пор я имплементил только серверную часть Kerberos аутентификации. И там токет брался из заголовка запроса, что приходил из браузера. То есть меня не парило кто его генерирует. Как ни странно, но вменяемого описания как получить токен я не нашёл на просторах интернета. Пришлось лепить самому. Получилось такое:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
import java.net.URL; import java.security.PrivilegedExceptionAction; import java.util.Base64; import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import org.ietf.jgss.GSSContext; import static net.sourceforge.spnego.SpnegoProvider.getClientCredential; import static net.sourceforge.spnego.SpnegoProvider.getGSSContext; public class KbHeaderGenerator { public static void main(String[] args) throws Exception { String loginContextName = "my-client"; String siteUrl = "http://my-server-host"; LoginContext loginContext = new LoginContext(loginContextName); loginContext.login(); Subject subject = loginContext.getSubject(); GSSContext context = getGSSContext(getClientCredential(subject), new URL(siteUrl)); byte[] token = Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() { @Override public byte[] run() throws Exception { return context.initSecContext(new byte[0], 0, 0); } }); System.out.println("Negotiate " + new String(Base64.getEncoder().encode(token))); } } |
Чтобы запустить это приложение нужна одна зависимость:
|
1 2 3 4 |
<dependency> <groupId>spnego</groupId> <artifactId>spnego</artifactId> </dependency> |
А также создать файл login.conf:
|
1 2 3 4 |
my-client { com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true; }; |
и запускать приложение с параметром -Djava.security.auth.login.config=login.conf
Замечание
Из переменной siteUrl будет вытягиваться хост. И он должен совпадать с хостом в принципале того сабжекта, который будет аутентифицировать токен.