Kerberos из Java - получение субъекта для текущего пользователя, прошедшего проверку - PullRequest
5 голосов
/ 11 июня 2009

У нас есть домен kerberos в моей компании, и я использую несколько примеров Java / Kerberos . Вопрос, который у меня есть, касается механизма входа в систему с точки зрения сервера. При запуске примера сервера GssServer.java мне нужно получить javax.security.auth.Subject; в предоставленном коде это через LoginContext таким образом:

// Create a LoginContext with a callback handler and login
LoginContext context = new LoginContext(name, new TextCallbackHandler());
context.login();

Subject subject = context.getSubject();

Все в порядке, и когда я запускаю пример, я вижу прекрасную подсказку для входа. Однако моя проблема заключается в том, что на самом деле не , как мой сервер будет работать, и как меня учили понимать, как я должен представлять сервисы из домена Kerberos. В примере GssServer проблема заключается в том, что мой сервер (читай: служба) не должен проходить проверку подлинности на KDC, чтобы предоставлять свою услугу клиентам. Для этого достаточно иметь доступ к файлу keytab на стороне сервера. Так для примера конфигурации:

//jaas-krb5.conf
server {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    keyTab="/home/myusr/my-server.keytab"
    principal="myserv/mymachine.some.domain";
};

А в коде Java:

GSSManager manager = GSSManager.getInstance();
Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
GSSName gssName = manager.createName("myserv/mymachine.some.domain@THE.REALM.COM", 
                                     GSSName.NT_HOSTBASED_SERVICE);
GSSCredential serverCreds = manager.createCredential(gssName,
                                     GSSCredential.DEFAULT_LIFETIME,
                                     krb5Mechanism,
                                     GSSCredential.ACCEPT_ONLY);

Проблема в том, что информация server в файле jaas-krb5.conf недоступна , если Я аутентифицирую себя через строку:

Jaas.loginAndAction("server", action);     

Мне не нужно проходить эту аутентификацию! Но если я не аутентифицирую себя, я получаю:

Exception in thread "main" GSSException: No valid credentials provided (Mechanism level: Attempt to obtain new ACCEPT credentials failed!)
    at sun.security.jgss.krb5.Krb5AcceptCredential.getKeysFromSubject(Krb5AcceptCredential.java:188)
    at sun.security.jgss.krb5.Krb5AcceptCredential.getInstance(Krb5AcceptCredential.java:73)
    at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:77)
    at sun.security.jgss.GSSManagerImpl.getCredentialElement(GSSManagerImpl.java:149)
    at sun.security.jgss.GSSCredentialImpl.add(GSSCredentialImpl.java:389)
    at sun.security.jgss.GSSCredentialImpl.<init>(GSSCredentialImpl.java:45)
    at sun.security.jgss.GSSManagerImpl.createCredential(GSSManagerImpl.java:102)
    at gsa.hk.GssServer$GssServerAction.run(GssServer.java:79)
    at gsa.hk.GssServer.main(GssServer.java:57)
Caused by: javax.security.auth.login.LoginException: No LoginModules configured for com.sun.security.jgss.accept
    at javax.security.auth.login.LoginContext.init(LoginContext.java:256)
    at javax.security.auth.login.LoginContext.<init>(LoginContext.java:403)
    at sun.security.jgss.LoginUtility.login(LoginUtility.java:72)
    at sun.security.jgss.krb5.Krb5Util.getKeysFromSubject(Krb5Util.java:205)
    at sun.security.jgss.krb5.Krb5AcceptCredential$1.run(Krb5AcceptCredential.java:184)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.security.jgss.krb5.Krb5AcceptCredential.getKeysFromSubject(Krb5AcceptCredential.java:181)
    ... 8 more

Не удивительно, что есть проблема. В конце концов, если у меня нет ручки по теме server, как я могу узнать, где находится мой keytab или какую услугу я предоставляю?

Итак, мой вопрос: как я могу сообщить GSS API о keytab / service без аутентификации в коде?

1 Ответ

5 голосов
/ 15 июня 2009

OK. Таким образом, получается, что чрезвычайно просто , если вы знаете, что файл keytab может использоваться вместо аутентификации Это немного описано в JavaDoc для Krb5LoginModule

В основном, если я

loginAndAction("anything", action)

Тогда мой конфиг должен выглядеть так:

//jaas-krb5.conf
anything {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    doNotPrompt=true
    keyTab="/home/myusr/my-server.keytab"
    principal="myserv/mymachine.some.domain";
};

Важным битом является добавление doNotPrompt=true. Когда это свойство установлено, код сервера использует информацию в таблице ключей

...