java.sql.SQLRecoverableException: I/O error: The service in process is not supported. Operation not available (Mechanism level: KRB_CRED not generated correctly).
I am getting this exception when my HikariDataSource tries to establish a connection to my oracle database using kerberos as a means of authentication.
I'm sure the problem has something to do with my principle not being accepted even though my credential cache file works perfectly fine for my other Java 8 projects.
The reason I think it's an issue with the principal is because I have a separate credential cache file that is generated on my server that uses a different principal than what I would use locally. That credential cache file from my server works perfectly fine when used locally for this Java 11 project. However, I am unable to locally generate credential cache files with that principal.
Also, I'm using the same krb5.conf file, so I don't understand how 1 service accepts my main, but not the other... I also made sure to use the java 11 version of the kinit.exe file when running the following command, though it didn't I think that should matter.
$kinit -c credential_cache_file instance@domain.realmUsing other flags like -A -p -f also gives me a separate error, but that type of credential cache file won't work for any of my Java 8 or Java 11 services.
java.nio.BufferOverflowException: null
Actually a little more information and stacktrace would have helped debug the problem. Based on the information provided above,
This exception happens when there is a mismatch in the kerberos credential file. Then GSSException occurs and this message is generated.
Operation unavailable (Mechanism level: KRB_CRED not generated correctly.)code flow
Step 1: This message is part of the Krb5Context class. This is InquireType what KRB5_GET_KRB_CRED means is an attribute type to retrieve the KRB_CRED message that an initiator is about to send to an acceptor.
Bindings: Krb5Context Query Type
try { byte[] krbCred = new KrbCred(tgt, serviceCreds, key).getMessage(); return new KerberosCredMessage( sender, recipient, krbCred); } catch (KrbException | IOException e) { GSSException gsse = new GSSException(GSSException.UNAVAILABLE, -1, "KRB_CRED not generated correctly."); gsse.initCause(e); throw gsse; } Step 2: Then you call the KrbCred class and here the validation fails. This class wraps the KRB-CRED message that a client uses to send its delegated credentials to a server. In the condition check there is a discrepancy in the Client of the Service Ticket with the client in the Ticket Granting Ticket. So, as you mentioned, it looks like a main problem to me. Link: KrbCred
PrincipalName client = tgt.getClient(); PrincipalName tgService = tgt.getServer(); if (!serviceTicket.getClient().equals(client)) throw new KrbException(Krb5.KRB_ERR_GENERIC, Step 3: First KrbException is thrown, then it is caught by catch block and GSSException is returned with message as Operation unavailable . Link: GSS exception
Changes between Java 8 and Java 11
There have been many kerberos changes in Java 11 . You can find it in the changelog . E.g
There is less InquireType in Krb5Context Java 8 compared to Krb5Context Java 11.
possible solution
The Kerberos client you are currently using may not support the 'canonicalize' setting in the configuration file (krb5.conf) . As a result, the name canonicalization behavior cannot be customized. The client will claim support for it on every TGT request if sun.security.krb5.disableReferrals is false , and the KDC service can change the name of the client.
JDK 11: The ' canonicalize ' flag in the krb5.conf file is now compatible with the JDK Kerberos implementation. When set to true. The new default behavior is different from previous versions, where clients always requested name canonicalization in TGT requests to KDC services (provided that RFC 6806 support was not explicitly disabled with the sun.security system). .krb5.disableReferrals or the security properties).
This problem was also seen in some Java versions less than 8 (1.8.0_242). You can try the example in the ticket to reproduce. JDK-8239385
More information JDK-8244465
Cross-realm referral support is enabled by default and 5 is the maximum number of referral hops allowed. To disable it, set the sun.security.krb5.disableReferrals security or system property to false. To configure a custom maximum number of referral hops, set the sun.security.krb5.maxReferrals security or system property to any positive value.
You can try changing the JAAS configuration to use a ticket in the ticket cache created in advance using kinit.
You can also try updating the Java version.