Skip to main content

Client-side SPNEGO support?

2 replies [Last post]
audun_land
Offline
Joined: 2006-07-27

Hi,

I read something about SPNEGO being supported from the client-side in Mustang. I have been eager to try this out, but so far I've been unable to get it to work.

I have a client application which connects to a 'SPNEGO-compatible' server. The client connects in the following manner (error handling has been left out):

URL url = new URL("HTTP://myserv/spnegoTest/index.html");
URLConnection conn = url.openConnection();
HttpURLConnection hconn = (HttpURLConnection)conn;
conn.setRequestMethod("POST");
conn.connect();
InputStream inputStream = conn.getInputStream();
byte[] b = new byte[inputStream.available()];
for (int j = 0; j < b.length; j++) {
b[j] = (byte)inputStream.read();
}
String s = new String(b);
System.out.println(s);

This code works fine when the server responds with 401 and the header 'WWW-Authenticate' is set to 'NTLM', Java automagically sends the NTLM token to the server, and the user is authenticated properly.

When the server sends 'Negotiate', however, the code crashes with an IOException (Because of the 401). No token is sent to the server, and the user is not authenticated.

- JVM: jdk-6-rc-bin-b92-windows-i586-20_jul_2006.exe
- OS: WinXP SP2 (Both client and server)
- SPNEGO authentication on this server has been verified using Internet Explorer from this client.

I have been unable to find any documentation on this feature. Is there something else I need to be doing here in order to get SPNEGO to work from the client-side?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
weijun
Offline
Joined: 2005-07-20

"When the server sends 'Negotiate', however, the code crashes with an IOException (Because of the 401)."

BTW, we don't call that a crash. IOException is a checked exception that programmers should gracefully deal with. ;)

weijun
Offline
Joined: 2005-07-20

SPNEGO support is based on the JGSS/Krb5 mechanism, so there's quite some configurations.

First, you may need these 2 config files:

/********* krb5.conf ***********/
[libdefaults]
default_realm = AD.LOCAL
[realms]
AD.LOCAL = {
kdc = kdc.ad.local
}

/********* login.conf ***********/
com.sun.security.jgss.krb5.initiate {
com.sun.security.auth.module.Krb5LoginModule required doNotPrompt=false useTicketCache=true;
};

(Change "AD.LOCAL" and "kdc.ad.local" to your AD domain name and AD server name)

Then, provide some system properties while launching Java, like this:

java -Djava.security.krb5.conf=krb5.conf \
-Djava.security.auth.login.config=login.conf \
-Djavax.security.auth.useSubjectCredsOnly=false \
YourClassFile

There will be detailed documentation on this when JDK 6 is released, possibly as one of the new networking features.