java 11 Kerberos 身份验证主体错误 - KRB_CRED 未正确生成

jim*_*542 7 java oracle kerberos java-11

java.sql.SQLRecoverableException: IO Error: The service in process is not supported. Operation unavailable (Mechanism level: KRB_CRED not generated correctly.)
Run Code Online (Sandbox Code Playgroud)

当我尝试使用身份验证方式HikariDataSource与数据库建立连接时,我收到此异常。oraclekerberos

我确信这个问题与我的原则不被接受有关,尽管我的凭证缓存文件对于我的其他java 8项目来说工作得很好。

我认为主体存在问题的原因是因为我在服务器上生成了一个单独的凭据缓存文件,该文件使用的主体与我在本地使用的主体不同。当我的服务器中的凭证缓存文件在本地用于该java 11项目时,它工作得非常好。但是,我无法使用该主体在本地生成凭据缓存文件。

此外,我使用相同的krb5.conf文件,所以我不明白我的主体如何被 1 个服务接受,但不是另一个服务......我还确保在执行以下命令时使用java 11该文件的版本,尽管我不知道kinit.exe我认为这并不重要。

$kinit -c credential_cache_file instance@domain.realm
Run Code Online (Sandbox Code Playgroud)

使用其他标志(例如)-A -p -f也会给我一个单独的错误,但是这种类型的凭据缓存文件不适用于我的任何java 8java 11服务。

java.nio.BufferOverflowException: null
Run Code Online (Sandbox Code Playgroud)

编辑:我实际上得到的最低级别的错误是这样的。

Caused by: sun.security.krb5.KrbException: Invalid option in ticket request. (101)
Run Code Online (Sandbox Code Playgroud)

Tri*_*riS 4

实际上,更多的信息和堆栈跟踪将有助于调试问题。根据上述提供的信息,

\n

exception当 中存在不匹配时,就会发生这种情况kerberos credential。然后发生 GSSException 并生成此消息。

\n
Operation unavailable (Mechanism level: KRB_CRED not generated correctly.)\n
Run Code Online (Sandbox Code Playgroud)\n

代码流程

\n

步骤 1:\n此消息是Krb5Context课程的一部分。这InquireType意味着KRB5_GET_KRB_CRED它是一个属性类型,用于检索KRB_CRED发起者将要发送给接受者的消息。
\n链接: Krb5Context \xe2\x80\x83 InquireType

\n
try {\n     byte[] krbCred = new KrbCred(tgt, serviceCreds, key).getMessage();\n      return new KerberosCredMessage( sender, recipient, krbCred);\n    } catch (KrbException | IOException e) {\n       GSSException gsse = new GSSException(GSSException.UNAVAILABLE, -1,\n                            "KRB_CRED not generated correctly.");\n        gsse.initCause(e);\n        throw gsse;\n   }\n
Run Code Online (Sandbox Code Playgroud)\n

步骤 2:\n然后调用KrbCred类,此处验证失败。此类封装了客户端用来将其委托凭证发送到服务器的 KRB-CRED 消息。在条件检查中,服务票据的客户端与票据授予票据中的客户端不匹配。因此,正如您提到的,在我看来这是一个主要问题。\xc2\xa0 链接:KrbCred

\n
PrincipalName client = tgt.getClient();\nPrincipalName tgService = tgt.getServer();\nif (!serviceTicket.getClient().equals(client))\n    throw new KrbException(Krb5.KRB_ERR_GENERIC,\n
Run Code Online (Sandbox Code Playgroud)\n

第 3 步:首先KrbException抛出,然后被 catch 块捕获并GSSException以消息 as 抛出 Operation unavailable。\xc2\xa0 链接:\xc2\xa0 GSSException

\n

Java 8 和 Java 11 之间的变化

\n

kerberos中发生了很多变化Java 11您可以在变更日志中找到它。例如

\n\n

与Java 11 的Krb5Context相比,Java 8 的Krb5ContextInquireType中的数量更少。

\n

可能的解决方案

\n

Kerberos您使用的客户端当前可能不支持配置\'canonicalize\'文件中的设置(krb5.conf)。因此,名称规范化行为无法自定义。如果是,客户端将在每个TGT请求中声明支持它,并且 KDC 服务可能会更改客户端名称。sun.security.krb5.disableReferralsfalse

\n

JDK 11:JDK Kerberos 实现现在支持文件canonicalize中的 \' \' 标志。krb5.conf设置为 true 时。\n新的默认行为与以前的版本不同,在以前的版本中,客户端始终在服务TGT请求中请求名称规范化KDC(前提是未使用 sun.security.krb5.disableReferrals 系统或安全性显式禁用对RFC 6806的支持)特性)

\n

这个问题也出现在一些次要的Java8 版本(1.8.0_242)中。您可以尝试票证中的示例来重现。JDK-8239385
\n更多信息JDK-8244465

\n

默认情况下启用跨领域引用支持,并且 5 是允许的最大引用跃点数。要关闭它,请将sun.security.krb5.disableReferrals安全或系统属性设置为 false。要配置自定义最大引用跃点数,请将sun.security.krb5.maxReferrals安全或系统属性设置为任何正值。

\n

您可以尝试更改JAAS配置以使用预先使用 kinit 创建的票证缓存中的票证。
\n您也可以尝试升级java版本。

\n

评论部分讨论的更新

\n
by: sun.security.krb5.KrbException: Invalid option in ticket request. (101)\n
Run Code Online (Sandbox Code Playgroud)\n

这可以链接到proxiable=true您的 krb5.conf 中。删除该值有助于解决问题。

\n
Kerberos authentication fails with \xe2\x80\x9cjava.nio.BufferOverflowException"\n
Run Code Online (Sandbox Code Playgroud)\n

此问题可能与 JDBC 驱动程序有关。当前版本可能不支持该操作。升级或降级oracle jdbc driver可能会导致解决问题。

\n

  • 对一个非常复杂的话题的非常深刻的解释! (2认同)