I am trying to perform kerberos constrained delegation through my java code. I've a keytab file, SPN attached to the user, and the delegation enabled for the SPN to that user. When I am trying to login with Keytab, I am getting the SPN's TGT. However, the "forwardable" flag is set to false on this ticket.
In order to impersonate the other user, I need this flag set to true.
Note: ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION flag is set on the SPN user.
Any help is highly appreciated.
private void tryKrb5Module() throws LoginException {
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("javax.security.auth.useSubjectCredsOnly","true");//has no impact
final Subject subject = new Subject();
final Krb5LoginModule krb5LoginModule = new Krb5LoginModule();
final Map<String,String> optionMap = new HashMap<String,String>();
optionMap.put("keyTab", "c:\\ticket\\delegationUser.keytab");
optionMap.put("principal", "TEST/TEST"); // default realm
optionMap.put("doNotPrompt", "true");
optionMap.put("refreshKrb5Config", "true");
optionMap.put("useTicketCache", "true");
optionMap.put("renewTGT", "true");
optionMap.put("useKeyTab", "true");
optionMap.put("storeKey", "true");
optionMap.put("isInitiator", "true");
krb5LoginModule.initialize(subject, null, new HashMap<String,String>(), optionMap);
boolean loginOk = krb5LoginModule.login();
System.out.println("======= login: " + loginOk);
boolean commitOk = krb5LoginModule.commit();
System.out.println("======= commit: " + commitOk);
System.out.println("======= Principal from subject: " + subject.getPrincipals());
}
I figured out the solution. You need to set the krb config file in the system path. Then only the ticket obtained from the keytab is "forwardaable". Surprisingly, this is not mentioned anywhere clearly.
System.setProperty("java.security.krb5.conf", "path_to_krb_config");
Also make sure you have mentioned "forwardable = true" in your krb config file. Pasting example krb config file below:
[libdefaults]
default_realm = DOMAIN.COM
default_tkt_enctypes = aes128-cts aes128-cts-hmac-sha1-96 aes256-cts aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
default_tgs_enctypes = aes128-cts aes128-cts-hmac-sha1-96 aes256-cts aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
permitted_enctypes = aes128-cts aes128-cts-hmac-sha1-96 aes256-cts aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
dns_lookup_kdc = true
dns_lookup_realm = false
forwardable = true
[realms]
DOMAIN.COM = {
kdc = KDC_HOST.DOMAIN.COM
admin_server = KDC_HOST.DOMAIN.COM
default_domain = DOMAIN.COM
}
[domain_realms]
domain.com = DOMAIN.COM
.domain.com = DOMAIN.COM