3

到目前为止,我们使用 MS JDBC Driver 4.0 使用集成安全性和 Java Kerberos 连接到 SQL Server 2008,一切正常。

这是代码:

弹簧上下文:

<!-- ***** Data Source Configuration ***** -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
    <property name="url"
        value="jdbc:jtds:sqlserver://<serverName>:<port>;databaseName=<DBName>;integratedSecurity=true;authenticationScheme=JavaKerberos; />
    <property name="initialSize" value="5" />
    <property name="maxActive" value="2" />
    <property name="defaultAutoCommit" value="false" />
</bean>

<!-- ***** Transaction Manager ***** -->
<bean id="txManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />

<!-- ***** JDBC Configuration ***** -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <constructor-arg type="javax.sql.DataSource" ref="dataSource" />
</bean>

login.conf 文件:

com.sun.security.jgss.krb5.initiate {
   com.sun.security.auth.module.Krb5LoginModule required
   useTicketCache=false
   doNotPrompt=true
   useKeyTab=true
   keyTab="C:/myKeyTABFile"
   principal="me@org.foo.com"
   storeKey=true
   debug=true
};

krb5.conf 文件:

[libdefaults]
    default_realm = org.foo.com
    dns_lookup_realm = false
    dns_lookup_kdc = true
    ticket_lifetime = 1s
    forwardable = yes
    #udp_preference_limit = 1

[realms]
    org.foo.com = {
      kdc = org.foo.com
      default_domain = org.foo.com
    }

[domain_realm]
    .org.foo.com = org.foo.com

[login]
    krb4_convert = true
    krb4_get_tickets = false

我们在运行项目时传递了以下参数:

-Djava.security.krb5.debug=true 
-Djava.security.auth.login.config="C:\login.conf" 
-Djava.security.krb5.conf="C:\krb5.conf

现在,我们决定使用 jTDS 代替 MS JDBC 驱动程序,我对上述配置进行了以下更改:

  1. 将驱动程序类从更改com.microsoft.sqlserver.jdbc.SQLServerDrivernet.sourceforge.jtds.jdbc.Driver
  2. 将连接字符串从更改jdbc:sqlserver://...jdbc:jtds:sqlserver://...
  3. 将 jTDS JAR 和 NTLM 身份验证 DLL 文件添加到类路径

但它给了我以下错误:

org.apache.commons 的线程“main” org.apache.commons.dbcp.SQLNestedException 中的异常:无法创建 PoolableConnectionFactory(I/O 错误:GSS 失败:未提供有效凭据(机制级别:找不到任何 Kerberos tgt)) .dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1549) 在 org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1388) 在 org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044 ) at org.foo.utils.Foo.main(Foo.java:51) 原因:java.sql.SQLException:I/O 错误:GSS 失败:未提供有效凭据(机制级别:找不到任何 Kerberos tgt)在 net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:654) 在 net.sourceforge.jtds.jdbc.JtdsConnection.(JtdsConnection.java:371) 在 net。sourceforge.jtds.jdbc.Driver.connect(Driver.java:184) at org.apache.commons.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:38) at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory. java:582) at org.apache.commons.dbcp.BasicDataSource.validateConnectionFactory(BasicDataSource.java:1556) at org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1545) ... 3 更多原因: java.io.IOException:GSS 失败:net.sourceforge.jtds.jdbc.TdsCore.sendMSLoginPkt(TdsCore.java:1976) 在 net.sourceforge.jtds 中未提供有效凭据(机制级别:无法找到任何 Kerberos tgt)。 jdbc.TdsCore.login(TdsCore.java:617) ... 还有 9 个DriverConnectionFactory.createConnection(DriverConnectionFactory.java:38) at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:582) at org.apache.commons.dbcp.BasicDataSource.validateConnectionFactory(BasicDataSource.java:1556) at org .apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1545) ... 3 更多原因:java.io.IOException:GSS 失败:未提供有效凭据(机制级别:找不到任何 Kerberos tgt) net.sourceforge.jtds.jdbc.TdsCore.sendMSLoginPkt(TdsCore.java:1976) 在 net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:617) ... 9 更多DriverConnectionFactory.createConnection(DriverConnectionFactory.java:38) at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:582) at org.apache.commons.dbcp.BasicDataSource.validateConnectionFactory(BasicDataSource.java:1556) at org .apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1545) ... 3 更多原因:java.io.IOException:GSS 失败:未提供有效凭据(机制级别:找不到任何 Kerberos tgt) net.sourceforge.jtds.jdbc.TdsCore.sendMSLoginPkt(TdsCore.java:1976) 在 net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:617) ... 9 更多java:582) at org.apache.commons.dbcp.BasicDataSource.validateConnectionFactory(BasicDataSource.java:1556) at org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1545) ... 3 更多原因: java.io.IOException:GSS 失败:net.sourceforge.jtds.jdbc.TdsCore.sendMSLoginPkt(TdsCore.java:1976) 在 net.sourceforge.jtds 中未提供有效凭据(机制级别:无法找到任何 Kerberos tgt)。 jdbc.TdsCore.login(TdsCore.java:617) ... 还有 9 个java:582) at org.apache.commons.dbcp.BasicDataSource.validateConnectionFactory(BasicDataSource.java:1556) at org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1545) ... 3 更多原因: java.io.IOException:GSS 失败:net.sourceforge.jtds.jdbc.TdsCore.sendMSLoginPkt(TdsCore.java:1976) 在 net.sourceforge.jtds 中未提供有效凭据(机制级别:无法找到任何 Kerberos tgt)。 jdbc.TdsCore.login(TdsCore.java:617) ... 还有 9 个无法在 net.sourceforge.jtds.jdbc.TdsCore.sendMSLoginPkt(TdsCore.java:1976) 在 net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:617) 找到任何 Kerberos tgt) ... 还有 9 个无法在 net.sourceforge.jtds.jdbc.TdsCore.sendMSLoginPkt(TdsCore.java:1976) 在 net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:617) 找到任何 Kerberos tgt) ... 还有 9 个

我已经尝试过的事情:

  1. useKerberos=true;尝试将和附加useNTLMv2=true;到连接字符串
  2. 尝试附加domain=org.foo.com到连接字符串

但这似乎不起作用。我尝试在互联网上搜索,但找不到任何解决方案。

如果有人可以帮助我,将不胜感激。

4

1 回答 1

10

在搜索并尝试了不同的组合并查看了 jTDS 的源代码之后,这最终对我有用。

  1. useKerberos=true在连接字符串中使用属性

    来源: https ://sourceforge.net/p/jtds/patches/101/

  2. 传递 VM 参数-Djavax.security.auth.useSubjectCredsOnly=false

因此,最后在应用上述更改后,我的连接字符串如下所示:

jdbc:jtds:sqlserver://<serverName>:<port>;databaseName=<DBName>;useKerberos=true;

参数列表:

-Djava.security.krb5.debug=true 
-Djava.security.auth.login.config="C:\login.conf" 
-Djava.security.krb5.conf="C:\krb5.conf
-Djavax.security.auth.useSubjectCredsOnly=false
于 2016-03-15T12:41:05.743 回答