3
votes

I have a Java application running on Windows that needs to authenticate to a webapp using Kerberos/SPNEGO. I'm aware of how to configure JAAS to achieve this, but I find the Java (JDK6 and JDK7beta) Kerberos implementation to be lacking a couple important features I need. For example, support for referrals or using the DNS to figure out the realm of a host (I have a multi-realm environment).

Is there a third-party module that can implement authentication using the Windows native SSPI? We've already gone through the trouble of configuring our Windows clients to work within our environment, it'd be nice to not have to do it again for Java. I'm aware of Waffle and its WindowsLoginModule, but it doesn't seem to do SSO as it requires users to re-enter their credentials into the application.

1
Please note that the statement that "I'm aware of Waffle and its WindowsLoginModule, but it doesn't seem to do SSO as it requires users to re-enter their credentials into the application." is incorrect. Waffle does SSO, that's what it was designed for and any prompt is an issue in configuration.dB.
There is BTW enhancements going into latest OpenJDK to use default credentials of SSPI without the need of external libraries: openjdk.5641.n7.nabble.com/…eckes

1 Answers

3
votes

We've had a similar issue. The main problem for us was that the GSS-API implementation fails when using Windows UAC and we solved it using Waffle.

Waffle is basically a wrapper for the JNA calls to SSPI. We've managed to implement SSO using Waffle by overriding the class sun.net.www.protocol.http.NegotiatorImpl:

package sun.net.www.protocol.http;

import java.io.IOException;
import waffle.windows.auth.impl.WindowsSecurityContextImpl;

public class NegotiatorImpl extends Negotiator {

private String serviceName;

public NegotiatorImpl(HttpCallerInfo hci) throws IOException {
    this.serviceName = "HTTP/" + hci.host.toLowerCase();
}

    @Override
    public byte[] firstToken() throws IOException {
        return WindowsSecurityContextImpl.getCurrent("Negotiate", serviceName).getToken();
    }

    @Override
    public byte[] nextToken(byte[] in) throws IOException {
        return new byte[0];
    }
}

Then you can create a JAR with holding only this class and copy it along with the Waffle & JNA JARs to ./jre/lib/endorsed of your JVM. Using the Java Endorsed Standards Override Mechanism of the JVM, this replaces the default Negotiator implementation of the JVM.