Unable to make HTTP Post call using Kerberos (SONEGO) authentication on AEM | Community
Skip to main content
Level 3
April 7, 2025

Unable to make HTTP Post call using Kerberos (SONEGO) authentication on AEM

  • April 7, 2025
  • 1 reply
  • 542 views

Hi,

I need to make a simple HTTP Post call by passing kerberos ticket (SPNEGO) authenticated to get the results from another system on AEM 6.5.21.

This is the snippet that I am using:

 

DefaultHttpClient httpclient = new DefaultHttpClient(); System.setProperty("java.security.krb5.conf", "C:/Windows/krb5.ini"); System.setProperty("sun.security.krb5.debug", "true"); System.setProperty("javax.security.auth.useSubjectCredsOnly","false"); NegotiateSchemeFactory nsf = new NegotiateSchemeFactory(); httpclient.getAuthSchemes().register(AuthPolicy.SPNEGO, nsf); List<String> authpref = new ArrayList<>(); authpref.add(AuthPolicy.SPNEGO); httpclient.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF, authpref); HttpPost request = new HttpPost("url"); HttpEntity entity = new StringEntity(jsonPayload, "UTF-8"); HttpResponse response = httpclient.execute(request);

I know that DefaultHttpClient is deprecated. (Planning to changing that once I get the success response)

 

I am not able to get the kerberos ticket, even after passing the krb5.ini file location. I have manually created the krb5.ini file with kbc and other required details in the specified location, but I get 401 unauthorized on trying to make the call.

 

Has anyone faced similar error. Anyone input will be helpful. Thank you.

 

1 reply

giuseppebaglio
Level 10
April 7, 2025

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:

  1. Missing Credentials Provider: Your code sets up the NegotiateSchemeFactory but doesn't configure a credentials provider to supply the user credentials.

  2. Incorrect Authentication Preference: You're setting PROXY_AUTH_PREF when you likely need AuthPNames.TARGET_AUTH_PREF for direct server authentication.

  3. Request Entity Not Set: In your code snippet, you create a StringEntity but don't actually set it on the request.

  4. 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:

  • Failed credential acquisition

  • Incorrect Service Principal Name formats

  • KDC communication issues

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.