Аутентификация экземпляра SQL Server как пользователя Windows через JDBC
Мне нужно поддерживать несколько типов баз данных для моего веб-приложения с поддержкой арендаторов. Среди прочего, я успешно поддержал Microsoft SQL Server, используя класс net.sourceforge.jtds.jdbc.Driver со строкой соединения, например "jdbc:jtds:sqlserver://192.168.1.189:1433/ApplicationName". Это работает, но требует, чтобы пользователь явно определял пользователя в экземпляре SQL Server и включал аутентификацию SQL Server.
Теперь требования неизбежно изменились, и мы должны поддерживать подключение к SQL Server через проверку подлинности Windows. Очевидно, для этого требуется какое-то изменение строки подключения, поскольку сервер базы данных должен каким-то образом различать, переданы ли учетные данные, передаваемые в подключение базы данных, для пользователя, определенного в установке SQL Server или в ОС Windows. Но что это?
Действуя по совету из интернета, если продвинулся до расширения строки соединения с ;useNTLMv2=true;domain=WORKGROUP
, Это, кажется, заставляет сервер базы данных знать, что я хочу аутентифицироваться как пользователь Windows, но фактический вход в систему завершается неудачно с
The login is from an untrusted domain and cannot be used with Windows authentication. (code 18452, state 28000)
Теперь, когда я установил тестирование, и приложение J2EE, и экземпляр SQL-сервера фактически находятся на одном компьютере (хотя в рабочем состоянии они могут и не быть), и все же этот компьютер недостаточно надежен для входа в систему? Очевидно, я упускаю большую часть головоломки здесь. Что нужно сделать, чтобы убедить экземпляр SQL Server в том, что пользователь, запустивший его, может фактически войти в него через JDBC?
редактировать
Поскольку мы уже потратили слишком много безуспешных усилий, пытаясь интегрировать наше веб-приложение с полным стеком инфраструктуры Microsoft (SQL Server, Active Directory, служба доменных имен...), я должен ограничить этот вопрос:
Кто-нибудь знает способ доступа к установке SQL Server с помощью учетной записи пользователя, определенной как "пользователь Windows", через JDBC из приложения J2EE, без использования Active Directory, машины Windows, на которой выполняется веб-приложение, и проприетарной библиотеки DLL? Награда за любое решение этой подзадачи. Вся проблема явно слишком широка, чтобы ответить в одном сообщении на форуме.
7 ответов
Я столкнулся с ошибкой
Логин из ненадежного домена и не может использоваться с аутентификацией Windows
когда экземпляр БД SQL Server 2012 был недавно обновлен до 2016 года. Чтобы использовать аутентификацию на основе AD с драйвером JTDS и SQL Server 2016, необходимо указать оба параметра: useNTLMv2=true
и domain=example.com
суффикс для установления соединения. Имя домена абсолютно необходимо, и я подтвердил это путем тестирования. Это с драйвером JTDS версии 1.3.1.
Пример рабочей строки соединения с использованием аутентификации на основе AD для БД SQL Server 2016 с JTDS 1.3.1:
jdbc:jtds:sqlserver://sqlserver2016db.example.com/MY_DB_NAME;domain=example.com;prepareSQL=2;useNTLMv2=true
То, что вы описываете, безусловно, представляется возможным. У меня SQL Server 2008 R2 Express работает на автономном сервере, и я смог подключиться, используя имя пользователя / пароль Windows на этом сервере через jTDS 1.3.1 с отдельного компьютера с Windows и из коробки Xubuntu 14.04.
На машине под управлением SQL Server я создал пользователя Windows с именем kilian. В самом SQL Server я создал SQL Login для NT AUTHORITY\Authenticated Users
, Затем в базе данных (с именем "myDb") я создал пользователя с именем "AuthenticatedUsers" для этого входа в SQL. Для простоты я дал этому пользователю права db_owner на базу данных.
Для "kilian" нет логина SQL и пользователя базы данных с таким именем.
Затем с двух других машин (рабочей станции Windows и коробки Xubuntu) я просто запустил это:
package com.example.jtdstest;
import java.sql.*;
public class JtdsTestMain {
public static void main(String[] args) {
try (Connection con = DriverManager.getConnection(
"jdbc:jtds:sqlserver://192.168.1.137:52865/myDb" +
";domain=whatever",
"kilian",
"4theBounty")) {
try (Statement s = con.createStatement()) {
String sql = "SELECT LastName FROM Clients WHERE ID=1";
try (ResultSet rs = s.executeQuery(sql)) {
rs.next();
System.out.println(rs.getString("LastName"));
}
}
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
Дополнительные примечания:
Я не должен был включать
useNTLMv2=true
, Я был в состоянии соединиться с или без этого параметра.Я должен был включить
domain=
сказать SQL Server не использовать аутентификацию SQL, но фактическое значение, которое я указал, не имело значения. (Я буквально использовал "что угодно", это не было имя сервера или имя рабочей группы, к которой он принадлежит.)
Я вижу две возможности: 1. Вы используете локальную системную учетную запись, которую сервер не поймет. В этом случае переключитесь на учетную запись домена.
- Проверка подлинности Windows имеет различные требования к учетным данным, и вы, возможно, не соответствуете им. В этом случае попробуйте изменить пароль в соответствии с требованиями.
Вполне возможно, что и то, и другое происходит.
Основная проблема - проверка подлинности Windows с полным решением Java (без DLL). Так что вы можете использовать одну из библиотек ниже:
- NTLM-аутентификация: http://ioplex.com/jespa.html
- основанная на Spring аутентификация Kerberos: http://projects.spring.io/spring-security-kerberos/
- Еще одна интегрированная библиотека Windows Auth - SPNEGO (не знаю много об этом)
Поэтому, как только ваше приложение аутентифицировано с помощью одной из приведенных выше библиотек, ваш JDBC должен нормально работать, используя "integratedSecurity=true;" и при необходимости "authenticationScheme=JavaKerberos".
См. этот другой пост SO, в котором описано, как подключиться к серверу SQL с аутентификацией Windows с компьютера Linux через JDBC
Во-первых, вы должны написать соединение jdbc следующим образом:
String url ="jdbc:sqlserver://PC01\inst01;databaseName=DB01;integratedSecurity=true";
затем
you need to enable the SQL Server TCP/IP Protocol in Sql Server Configuration Manager app. You can see the protocol in SQL Server Network Configuration.
Альтернативный метод
Альтернативное решение - использовать интегрированную безопасность. Это позволяет вашему приложению подключаться к базе данных как пользователь, в котором приложение в данный момент выполняется. Это включается добавлением integratedSecurity=true;
в свойствах строки подключения. Если у вас возникнут какие-либо проблемы, убедитесь, что sqljdbc_auth.dll доступен через classpath или в вашей библиотеке приложений.
Примечание по безопасности
Вы, вероятно, уже знаете, но просто должны сказать, что не предоставляйте доступ "Аутентифицированным пользователям" к вашей базе данных, как ранее предлагалось в рамках демонстрации. Определите, под какой учетной записью запускается ваше приложение, и предоставьте доступ только этому конкретному пользователю на сервере базы данных.
Источники / Дополнительная информация
- Документ MSDN о настройке строки подключения JDBC ( http://technet.microsoft.com/en-us/library/ms378428(v=sql.110).aspx)
Это моя настройка NiFi для драйвера jTDS:
URL соединения с базой данных: jdbc:jtds:sqlserver://192.168.1.189:1433;DOMAIN=domain_name
Мне не нужно было добавлять useNTLMv2=true
, но большинству людей это нужно, поэтому, если это не сработает, вы можете попробовать также:jdbc:jtds:sqlserver://192.168.1.189:1433;DOMAIN=domain_name;useNTLMv2=true
Имя класса драйвера базы данных: net.sourceforge.jtds.jdbc.Driver
Пользователь базы данных: domain_user_name (**without** @domain)
Пароль: domain_password
Запрос на проверку: select 1
Одной из возможных причин появления этой ошибки является то, что вы настраиваете источник данных для использования проверки подлинности Windows, а SQL Server использует режим расширенной защиты вместе с SSL (хотя я не уверен, требуется ли SSL). Этот режим требует, чтобы клиент отправил дополнительную информацию - подписанное имя участника службы (SPN) и токен привязки канала (CBT). Дополнительную информацию о режиме расширенной защиты см. Здесь. В настоящее время драйверы JTDS JDBC и Microsoft JDBC не поддерживают этот режим. Мне не удалось найти официального заявления от JTDS, но есть открытый тикет для драйверов Microsoft. Чтобы настроить режим расширенной защиты, перейдите в диспетчер конфигурации SQL Server, выберите свойства в разделе "Конфигурация сети SQL Server -> Протоколы для% вашего экземпляра%" и измените параметр расширенной защиты.