Реализовать аутентификацию Kerberos в Java

У нашего клиента есть приложение tomcat, развернутое на машине linux, и приложение будет вызывать веб-сервисы, которые находятся за пределами их сети. До сих пор работает нормально. Но теперь клиент установил Kerberos на своем сервере. Теперь нам нужно реализовать аутентификацию Kerberos в нашем Java-коде. Для тестирования мы дали приведенную ниже автономную Java-программу для выполнения в их среде.

public class testauthproxy {

/**
 * Uses HttpClient 4.3.4 and CommonsIO 2.4
 */

public static void main(String[] args) throws FileNotFoundException,
        IOException {           
        testProxyAuthentication("URL");
}

public static void testProxyAuthentication(String url) throws FileNotFoundException, IOException {      
    boolean skipPortAtKerberosDatabaseLookup = true;
    try {
        File loginConfig = createLoginConf();

        System.out.println("Created config '" + loginConfig.getAbsolutePath() + "':");
        System.out.println(IOUtils.toString(new FileReader(loginConfig)));

        System.setProperty("java.security.auth.login.config", loginConfig.toURI().toString());
        System.setProperty("java.security.krb5.conf", "/etc/krb5.conf");
        System.setProperty("sun.security.krb5.debug", "true");
        System.setProperty("javax.security.auth.useSubjectCredsOnly",
                "false");

                Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder
                .<AuthSchemeProvider> create()
                .register(AuthSchemes.SPNEGO,
                        new SPNegoSchemeFactory(
                                skipPortAtKerberosDatabaseLookup)).build();

        CloseableHttpClient client = HttpClients.custom()
                .setDefaultAuthSchemeRegistry(authSchemeRegistry).build();
        HttpClientContext context = HttpClientContext.create();
        BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();

        // This may seem odd, but specifying 'null' as principal tells java
        // to use the logged in user's credentials
        Credentials useJaasCreds = new Credentials() {

            public String getPassword() {
                return null;
            }

            public Principal getUserPrincipal() {
                return null;
            }

        };
        credentialsProvider.setCredentials(new AuthScope(null, -1, null),
                useJaasCreds);
        context.setCredentialsProvider(credentialsProvider);

        HttpGet httpget = new HttpGet(url);
        CloseableHttpResponse response = client.execute(httpget, context);
        String responseString = IOUtils.toString(response.getEntity()
                .getContent());

        System.out.println("HTTP Response: Success");
        System.out.println(responseString);

    } catch (FileNotFoundException e) {
        System.out.println("Error Occurred: "+e.getMessage());
        e.printStackTrace();            
    } catch (IOException e) {
        e.printStackTrace();
        System.out.println("Error Occurred: "+e.getMessage());
    }catch(Exception e){
        e.printStackTrace();
        System.out.println("Error Occurred: "+e.getMessage());
    }
}

/**
 * Creates a temporary krb5.conf [libdefaults] default_realm = <domain>
 * 
 * [realms] snb.ch = { kdc = <kdc> admin_server = <kdc> }
 */
private static File createLoginConf()
        throws IOException {
    File tempFile = File.createTempFile("login", ".conf");
    ArrayList<String> lines = new ArrayList<String>();
    lines.add("com.sun.security.jgss.krb5.initiate {");     
    lines.add("\t\tcom.sun.security.auth.module.Krb5LoginModule required useTicketCache=true;");        
    lines.add("\t};");

    FileWriter writer = new FileWriter(tempFile);
    IOUtils.writeLines(lines, "\n", writer);
    IOUtils.closeQuietly(writer);
    return tempFile;
}
}

Но мы получили ошибку тайм-аута соединения. Путь к файлу krb5.conf был правильным, но для login.conf я создал временный файл и назначил его во время выполнения.

Я искал в интернете, но не смог найти никакого решения. Подскажите, пожалуйста, есть ли другие альтернативные решения для этого?

0 ответов

У нашего клиента есть приложение tomcat, развернутое на Linux-машине, и приложение будет вызывать веб-службы, находящиеся за пределами их сети. До сих пор работает нормально. Но теперь клиент установил Kerberos на свой сервер. Теперь нам нужно реализовать аутентификацию Kerberos в нашем java-коде. Для тестирования мы предоставили нижеприведенную автономную Java-программу для выполнения в их среде.

Из этого я понимаю, что ваш клиент находится в другом домене, чем ваше приложение.

Kerberos в разных доменах требует еще нескольких обручей.

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

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