在普通的 Java 中(在 Adoptium 的 JDK 11 上没有服务器的简单本地应用程序),我可以成功地创建一个带有 Kerberos Auth 的数据库连接,如下所示:
String connectionUrl = "jdbc:sqlserver://SQL-Server-Name:14333;databaseName=test;integratedSecurity=true;authenticationScheme=JavaKerberos;applicationName=Test;";
Connection connection = DriverManager.getConnection(connectionUrl, user, password);
无需进一步的配置文件或 JVM 设置。
这适用于我的 Windows 工作站和为 Kerberos 配置的 Linux 服务器。所以我想,这证明 Kerberos 在操作系统级别上已正确配置并且可用于 JDBC。
现在我想通过 WildFly 26 中的 MSSQL JDBC (9.4) 将 Kerberos Auth 用于 Hibernate 的数据库连接。
<datasource jta="true" jndi-name="java:/datasources/someDS" pool-name="somePoolDS" enabled="true" use-java-context="true">
<connection-url>jdbc:sqlserver://SQL-Server-Name</connection-url>
<driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>
<datasource-class>com.microsoft.sqlserver.jdbc.SQLServerDataSource</datasource-class>
<connection-property name="serverName">SQL-Server-Name\Instanz03</connection-property>
<connection-property name="portNumber">14333</connection-property>
<connection-property name="databaseName">Test</connection-property>
<connection-property name="applicationName">test</connection-property>
<connection-property name="integratedSecurity">true</connection-property>
<connection-property name="authenticationScheme">JavaKerberos</connection-property>
<driver>sqlserver</driver>
<transaction-isolation>TRANSACTION_READ_UNCOMMITTED</transaction-isolation>
<pool>
<max-pool-size>100</max-pool-size>
</pool>
<security>
<user-name>UserXyz</user-name>
<password>PassXyz</password>
</security>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLValidConnectionChecker"/>
<background-validation>true</background-validation>
</validation>
</datasource>
<driver name="sqlserver" module="com.microsoft.mssql">
<xa-datasource-class>com.microsoft.sqlserver.jdbc.SQLServerXADataSource</xa-datasource-class>
<datasource-class>com.microsoft.sqlserver.jdbc.SQLServerDataSource</datasource-class>
</driver>
这不起作用,根本原因是:
Caused by: GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7))
at java.security.jgss/sun.security.jgss.krb5.Krb5Context.initSecContext(Krb5Context.java:773)
at java.security.jgss/sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:266)
at java.security.jgss/sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:196)
at com.microsoft.mssql//com.microsoft.sqlserver.jdbc.KerbAuthentication.intAuthHandShake(KerbAuthentication.java:158)
... 149 more
Caused by: KrbException: Server not found in Kerberos database (7)
at java.security.jgss/sun.security.krb5.KrbTgsRep.<init>(KrbTgsRep.java:70)
at java.security.jgss/sun.security.krb5.KrbTgsReq.getReply(KrbTgsReq.java:226)
at java.security.jgss/sun.security.krb5.KrbTgsReq.sendAndGetCreds(KrbTgsReq.java:237)
at java.security.jgss/sun.security.krb5.internal.CredentialsUtil.serviceCredsSingle(CredentialsUtil.java:477)
at java.security.jgss/sun.security.krb5.internal.CredentialsUtil.serviceCreds(CredentialsUtil.java:340)
at java.security.jgss/sun.security.krb5.internal.CredentialsUtil.serviceCreds(CredentialsUtil.java:314)
at java.security.jgss/sun.security.krb5.internal.CredentialsUtil.acquireServiceCreds(CredentialsUtil.java:169)
at java.security.jgss/sun.security.krb5.Credentials.acquireServiceCreds(Credentials.java:490)
at java.security.jgss/sun.security.jgss.krb5.Krb5Context.initSecContext(Krb5Context.java:697)
... 152 more
Caused by: KrbException: Identifier doesn't match expected value (906)
at java.security.jgss/sun.security.krb5.internal.KDCRep.init(KDCRep.java:140)
at java.security.jgss/sun.security.krb5.internal.TGSRep.init(TGSRep.java:65)
at java.security.jgss/sun.security.krb5.internal.TGSRep.<init>(TGSRep.java:60)
at java.security.jgss/sun.security.krb5.KrbTgsRep.<init>(KrbTgsRep.java:55)
... 160 more
但是,如果我将 authenticationScheme 更改为“NTLM”,它将立即起作用。我认为这证明了数据源配置本身是正确的。
所以问题是,为什么 Kerberos Auth for JDBC 不能在 WildFly 中工作?WildFly 是否会更改与 Kerberos Auth 相关的一些默认 JVM 设置?
我不知道,如果有任何提示如何弄清楚发生了什么,我会很高兴。