How do people make Java SPNEGO client work in Windows?
As of Java 13 there's now build-in support in the JDK for Windows' own GSS API (aka SSPI).
See Release Notes for Java 13 as well as JDK-6722928.
Update:
This has now been backported to Java 11. You'll need to use Java 11.0.10 or later. You can recognize if your JDK distribution has support for SSPI if it includes a file named sspi_bridge.dll
in the bin
directory.
There's even a ticket to backport to Java 8 too but as of Nov 2021 it hasn't been implemented.
Thanks for referencing my thread on the security-dev mailing list ;-) My mid-term goal is to make this patch available to Java 6+ through the endorsed class path. You might be interested in this WAFFLE ticket which I have created recently: https://github.com/dblock/waffle/issues/50
I have evaluated WAFFLE too but it is so not-Java-GSS-like that one has to create duplicate code, this is something I want to avoid by all means.
This entire issue is not exactly Oracle's fault. Microsoft is simply blocking any call to the session ticket through the LSA CallPackage
function. The pretext is security. I would really like to know how SSPI is able to create a service ticket when I cannot reasonable access the TGT. Therefore such a closed source solution sucks.
Right now at the moment, you have only three options:
- Obtain the TGT again through Java means
- Try WAFFLE
- Write custom code
I have burried the crappy registry key because it does not work for local admin with domain accounts anyway. In my case, Tomcat dev on Windows I have resorted to call Java's kinit in the meantime.
There is now a really good solution for this included in the Apache HTTP Client, using JNA to get the ticket from the native SSPI API. See this answer:
https://stackoverflow.com/a/22865583/381161
For someone looking for a simple solution with Java 8, Waffle is the best choice.
Code:
import java.net.URI;
import java.util.Base64;
import waffle.windows.auth.IWindowsSecurityContext;
import waffle.windows.auth.impl.WindowsSecurityContextImpl;
public class KerberosCredentiels {
/**
* Generate current user token using Kerberos ticket
*/
public String retrieveToken(URI uri) {
IWindowsSecurityContext clientContext = WindowsSecurityContextImpl.getCurrent("Kerberos", convertToSPN(uri));
byte[] token = clientContext.getToken();
return Base64.getEncoder().encodeToString(token);
}
private static String convertToSPN(URI uri) {
StringBuilder builder = new StringBuilder();
builder.append("http/");
builder.append(uri.getHost());
return builder.toString();
}
}
Maven dependencies:
<dependency>
<groupId>com.github.waffle</groupId>
<artifactId>waffle-jna</artifactId>
<version>1.8.3</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.3.0</version>
</dependency>