Kerberos и интегрированная безопасность с использованием драйвера jTDS

До сих пор мы использовали MS JDBC Driver 4.0 для подключения к SQL Server 2008 с использованием Integrated Security и Java Kerberos, и все работало нормально.

Вот код:

Весенний контекст:

<!-- ***** 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 Driver, и я внес следующие изменения в приведенную выше конфигурацию:

  1. Изменен класс водителя с com.microsoft.sqlserver.jdbc.SQLServerDriver в net.sourceforge.jtds.jdbc.Driver
  2. Изменена строка подключения с jdbc:sqlserver://... в jdbc:jtds:sqlserver://...
  3. Добавлены файлы JTDS JAR и файлы аутентификации NTLM в Classpath

Но это дает мне следующую ошибку:

Исключение в потоке "main" org.apache.commons.dbcp.SQLNestedException: не удается создать PoolableConnectionFactory (ошибка ввода-вывода: сбой GSS: не предоставлены действительные учетные данные (уровень механизма: не удалось найти любой tgt Kerberos)) на org.apache.commons.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: ошибка ввода-вывода: сбой GSS: не предоставлены действительные учетные данные (уровень механизма: не удалось найти какой-либо tgt Kerberos) в 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) в org.apache.commons.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:38) в org.apache.commons.dbcp.PoolableConnectionFactory.. 3 еще Причина: java.io.IOException: GSS Failed: Не предоставлены действительные учетные данные (уровень механизма: Не удалось найти любой Kerberos tgt) на net.sourceforge.jtds.jdbc.TdsCore.sendMSLoginPkt(TdsCore.java:1976) в net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:617) ... еще 9

Вещи, которые я уже пробовал:

  1. Попытка добавления useKerberos=true; а также useNTLMv2=true; к строке подключения
  2. Попытка добавления domain=org.foo.com к строке подключения

Но это не похоже на работу. Я пытался искать в Интернете, но не мог найти никакого решения.

Был бы признателен, если кто-то может помочь мне.

1 ответ

Решение

После поиска и опробования различных комбинаций и просмотра исходного кода jTDS это то, что в конце концов сработало для меня.

  1. Использовать собственность useKerberos=true в строке подключения

    Источник: https://sourceforge.net/p/jtds/patches/101/

  2. Пасс В.М. Аргумент -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
Другие вопросы по тегам