Unable to authenticate with apache http client 4.5 using kerberos ticket cache

adragomir :

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

Gerrit :

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

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=444785&siteId=1
Recommended