Получение билета службы Kerberos с помощью Waffle в Java

Я работаю над настоящим SSO в Java-приложении, работающем в Windows 10. В моем приложении уже есть аутентификация Kerberos с использованием GSSAPI Java (но, очевидно, это не работает ни в одной современной Windows, особенно со строгими политиками безопасности и пользователями домена), поэтому я хотел бы заменить текущую систему авторизации на Waffle с минимальными последствиями для общего дизайна приложения, что, я думаю, должно быть возможным, если я смогу каким-то образом получить экземпляр KerberosTicket. Я изо всех сил пытаюсь написать эту функцию, пока мне удалось запросить некоторый токен, но я действительно не знаю, что это за токен, он не соответствует формату билета Kerberos. Вот мой (на самом деле больше похоже на найденный онлайн-код):

public byte[] getServiceTicketSSPI() {
    final String securityPackage = "Kerberos";
    final String targetName = "<disclosed>";
    IWindowsCredentialsHandle clientCredentials = null;
    WindowsSecurityContextImpl clientContext = null;
    final String currentUser = WindowsAccountImpl.getCurrentUsername();
    try {
        clientCredentials = WindowsCredentialsHandleImpl.getCurrent(securityPackage);                               
        clientCredentials.initialize();
        // initial client security context
        clientContext = new WindowsSecurityContextImpl();
        clientContext.setPrincipalName(currentUser);
        clientContext.setCredentialsHandle(clientCredentials);
        clientContext.setSecurityPackage(securityPackage);
        final Sspi.SecBufferDesc continueToken = null;
        do {
            if(debug)
                System.out.println("Using target name: " + targetName);
            clientContext.initialize(clientContext.getHandle(), continueToken, targetName);
        } while(clientContext.isContinue());

        return clientContext.getToken();
    } finally {
        if (clientContext != null)
            clientContext.dispose();
        if (clientCredentials != null)
            clientCredentials.dispose();
    }
}

Честно говоря, я даже не уверен, позволяет ли SSPI увидеть настоящий билет. Я даже иду в правильном направлении с этим фрагментом? Я буду очень счастлив, поэтому увижу любые подсказки относительно того, что мне делать. Было бы идеально иметь экземпляр KerberosTicket в конце.


person Chlorek    schedule 24.04.2018    source источник
comment
Ваша функция возвращает токен, а не билет   -  person FlyingSheep    schedule 06.07.2018
comment
Как и в вашей ситуации, у нас есть существующий клиент JGSS и сервер на основе JGSS. Мы смогли расширить клиент, чтобы при желании использовать SSPI через Waffle вместо JGSS с кодом, аналогичным вашему выше. Код SSPI/Waffle создает токены Kerberos, которые принимаются чистой серверной частью JGSS, и может проверять токены, возвращенные с сервера JGSS. т. е. клиенты SSPI и GSS (в нашем случае) взаимозаменяемы. Насколько я вижу, ваш фрагмент движется в правильном направлении.   -  person FlyingSheep    schedule 06.07.2018
comment
Если токен, созданный вашим кодом, намного меньше, чем токен, созданный GSS, возможно, вы неправильно указали SPN (targetName); по крайней мере, это была наша первая ошибка.   -  person FlyingSheep    schedule 06.07.2018


Ответы (1)


Ниже приведены шаги для выполнения единого входа с использованием Waffle для автономного Java-клиента без использования сервера.

Создайте учетные данные клиента. Получите билет службы с помощью InitializeSecurityContext из WindowsSecurityContextImpl. Получите WindowsIdentity с помощью accessSecurityContext исходной ссылки WindowsAuthProviderImpl https://exceptionshub.com/getting-kerberos-service-ticket-using-waffle-in-java.html

Для sso клиент-сервер вы должны следовать https://code.dblock.org/2010/04/08/pure-java-waffle.html В приведенном ниже коде показан автономный java sso, использующий Kerberos.

import com.sun.jna.platform.win32.Sspi;
import waffle.windows.auth.IWindowsCredentialsHandle;
import waffle.windows.auth.IWindowsIdentity;
import waffle.windows.auth.IWindowsSecurityContext;
import waffle.windows.auth.impl.WindowsAccountImpl;
import waffle.windows.auth.impl.WindowsAuthProviderImpl;
import waffle.windows.auth.impl.WindowsCredentialsHandleImpl;
import waffle.windows.auth.impl.WindowsSecurityContextImpl;

public class KerberosSingleSignOn {
  public static void main() {
    try {
      System.out.println(getWindowsIdentity().getFqn());
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static IWindowsIdentity getWindowsIdentity() throws Exception {
    try {
      byte[] kerberosToken = getServiceTicketSSPI();
      WindowsAuthProviderImpl provider = new WindowsAuthProviderImpl();
      IWindowsSecurityContext securityContext = provider
        .acceptSecurityToken("client-connection", kerberosToken, "Kerberos");
      return securityContext.getIdentity();
    }
    catch (Exception e) {
      throw new Exception("Failed to process kerberos token");
    }
  }

  public static byte[] getServiceTicketSSPI() throws Exception {
    final String securityPackage = "Kerberos";
    IWindowsCredentialsHandle clientCredentials = null;
    WindowsSecurityContextImpl clientContext = null;
    final String currentUser = WindowsAccountImpl.getCurrentUsername();
    try {
      clientCredentials = WindowsCredentialsHandleImpl.getCurrent(securityPackage);
      clientCredentials.initialize();
      // initial client security context
      clientContext = new WindowsSecurityContextImpl();
      clientContext.setCredentialsHandle(clientCredentials.getHandle());
      /*OR 
       clientContext.setCredentialsHandle(clientCredentials);
       */
      clientContext.setSecurityPackage(securityPackage);
      final Sspi.SecBufferDesc continueToken = null;
      do {
        System.out.println("Using current username: " + currentUser);
        clientContext.initialize(clientContext.getHandle(), continueToken, currentUser);
      }
      while (clientContext.isContinue());

      return clientContext.getToken();
    }
    catch (Exception e) {
      throw new Exception("Failed to process kerberos token");
    }
    finally {
      if (clientContext != null)
        clientContext.dispose();
      if (clientCredentials != null)
        clientCredentials.dispose();
    }
  }
}
person Maneesh Sharma    schedule 13.01.2020