使用 jTDS 驱动程序的 Kerberos 和集成安全性
Kerberos and Integrated Security using jTDS Driver
到目前为止,我们使用 MS JDBC Driver 4.0 连接到 SQL Server 2008,使用 Integrated Security 和 Java Kerberos,一切正常。
代码如下:
Spring 上下文:
<!-- ***** 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 驱动程序,并且我在上面的配置中做了以下更改:
- 已将驱动程序 class 从
com.microsoft.sqlserver.jdbc.SQLServerDriver
更改为 net.sourceforge.jtds.jdbc.Driver
- 已将连接字符串从
jdbc:sqlserver://...
更改为 jdbc:jtds:sqlserver://...
- 已将 jTDS JAR 和 NTLM 身份验证 DLL 文件添加到类路径
但是它给我以下错误:
Exception in thread "main" org.apache.commons.dbcp.SQLNestedException:
Cannot create PoolableConnectionFactory (I/O Error: GSS Failed: No
valid credentials provided (Mechanism level: Failed to find any
Kerberos tgt)) at
org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1549)
at
org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1388)
at
org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
at org.foo.utils.Foo.main(Foo.java:51)
Caused by: java.sql.SQLException: I/O Error: GSS Failed: No valid
credentials provided (Mechanism level: Failed to find any Kerberos
tgt) at net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:654) at
net.sourceforge.jtds.jdbc.JtdsConnection.(JtdsConnection.java:371)
at 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 more Caused by: java.io.IOException: GSS Failed: No valid
credentials provided (Mechanism level: Failed to find any Kerberos
tgt) at
net.sourceforge.jtds.jdbc.TdsCore.sendMSLoginPkt(TdsCore.java:1976)
at net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:617) ... 9
more
我已经尝试过的东西:
- 尝试将
useKerberos=true;
和 useNTLMv2=true;
附加到连接字符串
- 尝试将
domain=org.foo.com
附加到连接字符串
但它似乎不起作用。我尝试在互联网上搜索但找不到任何解决方案。
如果有人能帮助我,我将不胜感激。
在搜索和尝试不同的组合并查看 jTDS 的源代码之后,这就是最终对我有用的方法。
在连接字符串中使用属性useKerberos=true
传递 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
到目前为止,我们使用 MS JDBC Driver 4.0 连接到 SQL Server 2008,使用 Integrated Security 和 Java Kerberos,一切正常。
代码如下:
Spring 上下文:
<!-- ***** 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 驱动程序,并且我在上面的配置中做了以下更改:
- 已将驱动程序 class 从
com.microsoft.sqlserver.jdbc.SQLServerDriver
更改为net.sourceforge.jtds.jdbc.Driver
- 已将连接字符串从
jdbc:sqlserver://...
更改为jdbc:jtds:sqlserver://...
- 已将 jTDS JAR 和 NTLM 身份验证 DLL 文件添加到类路径
但是它给我以下错误:
Exception in thread "main" org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (I/O Error: GSS Failed: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)) at org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1549) at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1388) at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044) at org.foo.utils.Foo.main(Foo.java:51) Caused by: java.sql.SQLException: I/O Error: GSS Failed: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt) at net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:654) at net.sourceforge.jtds.jdbc.JtdsConnection.(JtdsConnection.java:371) at 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 more Caused by: java.io.IOException: GSS Failed: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt) at net.sourceforge.jtds.jdbc.TdsCore.sendMSLoginPkt(TdsCore.java:1976) at net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:617) ... 9 more
我已经尝试过的东西:
- 尝试将
useKerberos=true;
和useNTLMv2=true;
附加到连接字符串 - 尝试将
domain=org.foo.com
附加到连接字符串
但它似乎不起作用。我尝试在互联网上搜索但找不到任何解决方案。
如果有人能帮助我,我将不胜感激。
在搜索和尝试不同的组合并查看 jTDS 的源代码之后,这就是最终对我有用的方法。
在连接字符串中使用属性
useKerberos=true
传递 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