java.sql.SQLRecoverableException: Error de E/S: el servicio en proceso no es compatible. Operación no disponible (Nivel de mecanismo: KRB_CRED no generado correctamente).
Obtengo esta excepción cuando mi HikariDataSource intenta establecer una conexión con mi base de datos de Oracle mediante el uso de kerberos como medio de autenticación.
Estoy seguro de que el problema tiene algo que ver con que mi principio no se acepta a pesar de que mi archivo de caché de credenciales funciona perfectamente bien para mis otros proyectos de Java 8.
La razón por la que creo que es un problema con el principal es porque tengo un archivo de caché de credenciales separado que se genera en mi servidor que usa un principal diferente al que usaría localmente. Ese archivo de caché de credenciales de mi servidor funciona perfectamente bien cuando se usa localmente para este proyecto Java 11. Sin embargo, no puedo generar localmente archivos de caché de credenciales con ese principal.
Además, estoy usando el mismo archivo krb5.conf, así que no entiendo cómo 1 servicio acepta mi principal, pero no otro... También me aseguré de usar la versión java 11 del archivo kinit.exe cuando ejecutando el siguiente comando, aunque no creo que eso deba importar.
$kinit -c credential_cache_file instance@domain.realm
El uso de otras marcas como -A -p -f también me da un error por separado, pero ese tipo de archivo de caché de credenciales no funcionará para ninguno de mis servicios Java 8 o Java 11.
java.nio.BufferOverflowException: nulo
En realidad, un poco más de información y stacktrace habrían ayudado a depurar el problema. Según la información proporcionada anteriormente,
Esto exceptionsucede cuando hay una falta de coincidencia en el archivo kerberos credential. Entonces ocurre GSSException y se genera este mensaje.
Operation unavailable (Mechanism level: KRB_CRED not generated correctly.)
Flujo de código
Paso 1: Este mensaje es parte de Krb5Contextla clase. Esto es InquireTypelo KRB5_GET_KRB_CREDque significa que es un tipo de atributo para recuperar el KRB_CREDmensaje que un iniciador está a punto de enviar a un aceptador.
Enlaces: Krb5Context Tipo de consulta
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;
}
Paso 2: luego llama a KrbCredla clase y aquí falla la validación. Esta clase encapsula el mensaje KRB-CRED que utiliza un cliente para enviar sus credenciales delegadas a un servidor. En la verificación de condición hay una discrepancia en el Cliente del Ticket de Servicio con el cliente en el Ticket de Otorgamiento de Tickets. Entonces, como mencionaste, me parece un problema principal. Enlace: KrbCred
PrincipalName client = tgt.getClient();
PrincipalName tgService = tgt.getServer();
if (!serviceTicket.getClient().equals(client))
throw new KrbException(Krb5.KRB_ERR_GENERIC,
Paso 3: primero KrbExceptionse lanza, luego es capturado por el bloque catch y GSSExceptionse devuelve con el mensaje como Operation unavailable. Enlace: excepción GSS
Cambios entre Java 8 y Java 11
Ha habido muchos cambios kerberosen Java 11. Puedes encontrarlo en el registro de cambios . P.ej
Hay menos InquireTypeen Krb5Context de Java 8 en comparación con Krb5Context de Java 11.
Solución posible
Es posible que el Kerberoscliente que está utilizando actualmente no admita la 'canonicalize'configuración en el archivo de configuración (krb5.conf). Como resultado, el comportamiento de canonicalización de nombres no se puede personalizar. El cliente reclamará soporte para él en cada TGTsolicitud si sun.security.krb5.disableReferralses false, y el servicio KDC puede cambiar el nombre del cliente.
JDK 11: el canonicalizeindicador ' ' en el krb5.confarchivo ahora es compatible con la implementación de JDK Kerberos. Cuando se establece en verdadero. El nuevo comportamiento predeterminado es diferente al de las versiones anteriores, en las que los clientes siempre solicitaban la canonicalización de nombres en TGTlas solicitudes a KDClos servicios (siempre que la compatibilidad con RFC 6806 no se haya deshabilitado explícitamente con el sistema sun.security.krb5.disableReferrals o las propiedades de seguridad).
Este problema también se vio en algunas Javaversiones menores 8 (1.8.0_242). Puedes probar el ejemplo en el ticket para reproducir. JDK-8239385
Más información JDK-8244465
El soporte de referencias entre reinos está habilitado de forma predeterminada y 5 es el número máximo de saltos de referencia permitidos. Para desactivarlo, establezca la sun.security.krb5.disableReferralspropiedad de seguridad o del sistema en falso. Para configurar un número máximo personalizado de saltos de referencia, establezca la sun.security.krb5.maxReferralspropiedad de seguridad o del sistema en cualquier valor positivo.
Puede intentar cambiar la JAASconfiguración para usar un ticket en el caché de tickets creado por adelantado usando kinit.
También puede intentar actualizar la versión de Java.