Реализовать аутентификацию 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.