You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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文件,内容如下:
    SQLJDBCDriver {
        com.sun.security.auth.module.Krb5LoginModule required
        useTicketCache=true
        doNotPrompt=true;
    };
    
    然后通过VM参数指定:-Djava.security.auth.login.config=path/to/jaas.conf

3. 检查运行权限

确保Java应用在已登录Windows域的用户下运行,本地账户无法获取域用户的Kerberos票据。


内容的提问来源于stack exchange,提问作者Gong Yu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 18:08:11