The DefaultHttpClient you're using is not only deprecated but may also have version-specific issues with SPNEGO: https://andriymz.github.io/kerberos/spnego-authentication-fails-to-https-service.
Your current implementation has potential issues:
Missing Credentials Provider: Your code sets up the NegotiateSchemeFactory but doesn't configure a credentials provider to supply the user credentials.
Incorrect Authentication Preference: You're setting PROXY_AUTH_PREF when you likely need AuthPNames.TARGET_AUTH_PREF for direct server authentication.
Request Entity Not Set: In your code snippet, you create a StringEntity but don't actually set it on the request.
Potential krb5.ini Issues: The content and format of your krb5.ini file might not be correctly configured for your Kerberos realm.
Updated version (AI generated):
// Import necessary classes
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.impl.auth.SPNegoSchemeFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.params.AuthPNames;
import org.apache.http.client.params.ClientPNames;
import java.util.ArrayList;
import java.util.List;
// Set Kerberos properties
System.setProperty("java.security.krb5.conf", "C:/Windows/krb5.ini");
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
// Create and configure the HTTP client
DefaultHttpClient httpClient = new DefaultHttpClient();
// Create SPNEGO authentication scheme
SPNegoSchemeFactory spnegoSchemeFactory = new SPNegoSchemeFactory(true);
httpClient.getAuthSchemes().register("negotiate", spnegoSchemeFactory);
// Set authentication preference for target (not proxy)
List<String> authPrefs = new ArrayList<>();
authPrefs.add("negotiate");
httpClient.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF, authPrefs);
// Enable automatic authentication
httpClient.getParams().setBooleanParameter(ClientPNames.HANDLE_AUTHENTICATION, true);
// Create and configure the request
HttpPost request = new HttpPost("https://your-target-server.com/api/endpoint");
request.setHeader("Content-Type", "application/json");
// Set the request entity
StringEntity entity = new StringEntity(jsonPayload, "UTF-8");
request.setEntity(entity);
// Execute the request
HttpResponse response = httpClient.execute(request);
// Process the response
int statusCode = response.getStatusLine().getStatusCode();
// Handle response accordingly
Check your krb5.ini file, it should contain at minimum:
[libdefaults]
default_realm = YOUR_REALM.COM
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
[realms]
YOUR_REALM.COM = {
kdc = kdc1.your_realm.com
kdc = kdc2.your_realm.com (if applicable)
admin_server = kdc1.your_realm.com
}
[domain_realm]
.your_domain.com = YOUR_REALM.COM
your_domain.com = YOUR_REALM.COM
Ensure that the target service has the appropriate SPN registered, typically in the format HTTP/fully.qualified.hostname@REALM2. For Windows-based servers, you can register SPNs using the setspn command:
setspn -A HTTP/fully.qualified.hostname.com DOMAIN\service_account
Common Troubleshooting Steps
1. Verify Kerberos Ticket Acquisition
Before running your Java application, verify that you can manually obtain a Kerberos ticket:
kinit username@REALM
klist
2. Test with cURL
Test the endpoint using cURL with Kerberos authentication to verify the server configuration:
curl -i --negotiate -u : -v https://your-target-server.com/api/endpoint
3. Debug Kerberos Negotiations
Analyze the debug output enabled by sun.security.krb5.debug=true for specific error messages about:
4. Check for Channel Binding Issues
For HTTPS connections, some environments require channel binding (extended protection). If your environment supports HTTPS with channel binding, you may need to explicitly enable or disable this feature depending on your server configuration.
Your HTTP 401 error is likely caused by one of several common Kerberos configuration issues. If problems persist after implementing these changes, focus on the debug output to identify specific authentication failures in the Kerberos negotiation process. The error messages in the Kerberos debug logs will typically point to configuration issues with either the client or server setup.