I am executing an https request to a kerberos authenticated REST service. All is fine if I am using the keytab. However, I have a requirement that I should use the kerberos ticket cache file which is created when one logs in in the workstation using its password.
I'll replace the domain with MY_DOMAINE.COM
So, klist shows:
Ticket cache: FILE:/tmp/krb5cc_210007
Default principal: dragomira@MY_DOMAINE.COM
Valid starting Expires Service principal
05/15/18 07:21:51 05/15/18 17:21:51 krbtgt/MY_DOMAINE.COM@MY_DOMAINE.COM
renew until 05/22/18 06:18:22
Using curl like this works ok:
curl -k --negotiate -u : 'my_url' -v
Now, let's ho back to code. My login.conf is like this:
com.sun.security.jgss.login {
com.sun.security.auth.module.Krb5LoginModule required
client=TRUE
doNotPrompt=true
useTicketCache=true;
};
com.sun.security.jgss.initiate {
com.sun.security.auth.module.Krb5LoginModule required
client=TRUE
doNotPrompt=true
useTicketCache=true;
};
com.sun.security.jgss.accept {
com.sun.security.auth.module.Krb5LoginModule required
client=TRUE
doNotPrompt=true
useTicketCache=true;
};
The relevant java code for my http client which is et up for kerberos is:
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (chain, authType) -> true).build();
HostnameVerifier hostnameVerifier = new NoopHostnameVerifier();
Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
.register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory())
.build();
Credentials dummyCredentials = new NullCredentials();
CredentialsProvider credProv = new BasicCredentialsProvider();
credProv.setCredentials(new AuthScope(null, -1, null), dummyCredentials);
this.httpClient = HttpClientBuilder.create()
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
.setDefaultCredentialsProvider(credProv)
.setSSLContext(sslContext)
.setSSLHostnameVerifier(hostnameVerifier)
.build();
} catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
throw new RuntimeException(e.getMessage(), e);
}
Before this, I am setting these java proerties:
java.security.auth.login.config=/home/dragomira/kerberos/login.conf
java.security.krb5.conf=/etc/krb5.conf
sun.security.krb5.debug=true
javax.security.auth.useSubjectCredsOnly=false
The output of the kerberos log is:
Loaded from Java config
>>>KinitOptions cache name is /tmp/krb5cc_210007
>>>DEBUG <CCacheInputStream> client principal is dragomira@MY_DOMANIN.COM
>>>DEBUG <CCacheInputStream> server principal is krbtgt/MY_DOMANIN.COM@MY_DOMANIN.COM
>>>DEBUG <CCacheInputStream> key type: 18
>>>DEBUG <CCacheInputStream> auth time: Tue May 15 06:18:22 EDT 2018
>>>DEBUG <CCacheInputStream> start time: Tue May 15 07:21:51 EDT 2018
>>>DEBUG <CCacheInputStream> end time: Tue May 15 17:21:51 EDT 2018
>>>DEBUG <CCacheInputStream> renew_till time: Tue May 22 06:18:22 EDT 2018
>>> CCacheInputStream: readFlags() FORWARDABLE; RENEWABLE; INITIAL; PRE_AUTH;
>>>DEBUG <CCacheInputStream> client principal is dragomira@MY_DOMANIN.COM
>>>DEBUG <CCacheInputStream> server principal is HTTP/configuration.prd.int.MY_DOMANIN.COM@MY_DOMANIN.COM
>>>DEBUG <CCacheInputStream> key type: 23
>>>DEBUG <CCacheInputStream> auth time: Tue May 15 06:18:22 EDT 2018
>>>DEBUG <CCacheInputStream> start time: Tue May 15 07:57:49 EDT 2018
>>>DEBUG <CCacheInputStream> end time: Tue May 15 17:21:51 EDT 2018
>>>DEBUG <CCacheInputStream> renew_till time: Tue May 22 06:18:22 EDT 2018
>>> CCacheInputStream: readFlags() FORWARDABLE; RENEWABLE; PRE_AUTH;
>>> unsupported key type found the default TGT: 18
So it would seem to me that the ticket is read but no credentials are extracted from it since i receive in the end 401.
Must I do something special to apache http client 4.5 in order to use ticket tacke?
Kind regards
Based on the error:
unsupported key type found the default TGT: 18
Type 18 = aes-256-cts-hmac-sha1-96 (See IANA Kerberos Parameters)
I think you are using a JRE with limited strength JCE policy and have to set unlimited strength JCE policy.
On the Oracle downloads site for Oracle JRE. Check under Additional Resources the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE 8
Oracle Java SE downloads
See also: Oracle Java SE 8 technotes jgss
NOTE: The JCE framework within JDK includes an ability to enforce restrictions regarding the cryptographic algorithms and maximum cryptographic strengths available to applications. Such restrictions are specified in "jurisdiction policy files." The jurisdiction policy files bundled in Java SE limit the maximum key length. Hence, to use the AES256 encryption type, you will need to install the JCE crypto policy with the unlimited version to allow AES with 256-bit key.
Testing your policy (source):
jrunscript -e 'print (javax.crypto.Cipher.getMaxAllowedKeyLength("AES") >= 256);'
As of the start of 2018, Oracle JDK in all supported versions is beginning to ship with default unlimited strength JCE policy:
https://bugs.openjdk.java.net/browse/JDK-8189377
Also see these interesting workarounds with reflection, and a possible override setting for JRE9: https://stackoverflow.com/a/22492582/2824577
mmm...
Default principal: dragomira@MY_DOMAINE.COM
DEBUG client principal is dragomira@MY_DOMANIN.COM
DOMANIN?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With