Windows环境下JDBC配置Kerberos认证失败求助
问题描述
我在Windows系统中尝试通过JDBC使用Kerberos认证连接SQL Server:
- Java版本:Java 17
- mssql-jdbc版本:
com.microsoft.sqlserver:mssql-jdbc:12.6.1.jre11
我能通过Windows认证正常登录SQL Server Management Studio,但Java应用无法连接数据库,代码如下:
public static void main(String[] args) { try ( Connection connection = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;integratedSecurity=true;authenticationScheme=JavaKerberos;encrypt=true;trustServerCertificate=true;", "", ""); Statement statement = connection.createStatement(); ResultSet rs = statement.executeQuery("select 'abc'") ){ if(rs.next()){ System.out.println(rs.getString(1)); } } catch (SQLException e) { e.printStackTrace(); } }
运行应用时执行命令:java -Dsun.security.krb5.debug=true -jar kerberos-1.0-SNAPSHOT.jar,得到错误日志:
Java config name: null LSA: Found Ticket LSA: Made NewWeakGlobalRef LSA: Found PrincipalName LSA: Made NewWeakGlobalRef LSA: Found EncryptionKey LSA: Made NewWeakGlobalRef LSA: Found TicketFlags LSA: Made NewWeakGlobalRef LSA: Found KerberosTime LSA: Made NewWeakGlobalRef LSA: Found String LSA: Made NewWeakGlobalRef LSA: Found Ticket constructor LSA: Found PrincipalName constructor LSA: Found EncryptionKey constructor LSA: Found TicketFlags constructor LSA: Found KerberosTime constructor LSA: Finished OnLoad processing Native config name: C:\Windows\krb5.ini Loaded from native config >>>KinitOptions cache name is C:\Users\<***>\<***>\<***> >> Acquire default native Credentials Using builtin default etypes for default_tkt_enctypes default etypes for default_tkt_enctypes: 18 17 20 19. LSA: Found KrbCreds constructor LSA: Got handle to Kerberos package LSA: Response size is 1843 LSA: TICKET SessionKey KeyType is 18 LSA: Valid etype found: 18 LSA: Principal domain is *** LSA: Name type is 1 LSA: Name count is 1 LSA: Principal domain is *** LSA: Name type is 2 LSA: Name count is 2 LSA: Session key all zero. Stop. >>> Found no TGT's in native ccache com.microsoft.sqlserver.jdbc.SQLServerException: Kerberos Login failed: Integrated authentication failed. ClientConnectionId:c6f18883-621c-4647-9369-adb0578b406a due to javax.security.auth.login.LoginException (Cannot get any of properties: [user, USER] from con properties not available to garner authentication information from the user) at com.microsoft.sqlserver.jdbc.KerbAuthentication.initAuthInit(KerbAuthentication.java:130) at com.microsoft.sqlserver.jdbc.KerbAuthentication.generateClientContext(KerbAuthentication.java:238) at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:6587) at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:5402) at com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:5334) at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7739) at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:4384) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:3823) at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:3348) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:3179) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1953) at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1263) at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:681) at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:229) at com.mssql.Kerberos.main(Kerberos.java:8) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65) Caused by: javax.security.auth.login.LoginException: Cannot get any of properties: [user, USER] from con properties not available to garner authentication information from the user at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.promptForName(Krb5LoginModule.java:853) at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:689) at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:597) at java.base/javax.security.auth.login.LoginContext.invoke(LoginContext.java:755) at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:679) at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:677) at java.base/java.security.AccessController.doPrivileged(AccessController.java:712) at java.base/javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:677) at java.base/javax.security.auth.login.LoginContext.login(LoginContext.java:587) at com.microsoft.sqlserver.jdbc.KerbAuthentication.initAuthInit(KerbAuthentication.java:107) ... 22 more
请问是否遗漏了某些配置?
解决方案
从错误日志来看,核心问题是Java无法从系统获取Kerberos票据(TGT),同时提示缺少用户属性。可以从以下几个方面排查修复:
1. 切换认证方案为NativeAuthentication
Windows环境下更适合使用NativeAuthentication,它直接调用Windows本地SSPI获取认证凭据,无需额外配置Kerberos参数。
修改JDBC连接URL:
jdbc:sqlserver://localhost:1433;integratedSecurity=true;authenticationScheme=NativeAuthentication;encrypt=true;trustServerCertificate=true;
注意:需要将对应系统架构的mssql-jdbc_auth-12.6.1.x64.dll(64位)或mssql-jdbc_auth-12.6.1.x86.dll(32位)放入JRE的bin目录,或通过VM参数指定路径:-Djava.library.path=path/to/dll。
2. 补充Kerberos相关配置(若坚持使用JavaKerberos)
- 指定用户主体:在JDBC URL中添加
user参数,格式为DOMAIN\username或username@DOMAIN.COM - 确保存在有效TGT:命令行执行
klist查看票据,若无则执行kinit username@DOMAIN.COM获取 - 检查krb5.ini配置:确认
C:\Windows\krb5.ini的KDC和域信息正确,示例配置:[libdefaults] default_realm = YOUR_DOMAIN.COM default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac permitted_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac [realms] YOUR_DOMAIN.COM = { kdc = your-domain-controller.yourdomain.com admin_server = your-domain-controller.yourdomain.com } [domain_realm] .yourdomain.com = YOUR_DOMAIN.COM yourdomain.com = YOUR_DOMAIN.COM - 添加JAAS配置:创建
jaas.conf文件,内容如下:
然后通过VM参数指定:SQLJDBCDriver { com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true doNotPrompt=true; };-Djava.security.auth.login.config=path/to/jaas.conf
3. 检查运行权限
确保Java应用在已登录Windows域的用户下运行,本地账户无法获取域用户的Kerberos票据。
内容的提问来源于stack exchange,提问作者Gong Yu
相关产品推荐
相关产品推荐

