9

我必须为支持租户的 Web 应用程序支持多种数据库类型。其中,我成功地支持了 Microsoft 的 SQL Server,通过使用带有“jdbc:jtds:sqlserver://192.168.1.189:1433/ApplicationName”之类的连接字符串的 net.sourceforge.jtds.jdbc.Driver 类。这可行,但它要求用户在 SQL Server 实例中明确定义用户并启用 SQL Server 身份验证。

现在,不可避免地,需求发生了变化,我们应该支持通过 Windows 身份验证连接到 SQL Server。显然,这需要对连接字符串进行某种更改,因为数据库服务器必须能够以某种方式区分传递到数据库连接的凭据是针对 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 登录到它?

编辑

由于我们在尝试将我们的 Web 应用程序与完整的 Microsoft 基础架构堆栈(SQL Server、Active Directory、域名服务...)集成时已经付出了太多不成功的努力,所以我必须限制这个问题:

有没有人知道一种方法可以通过J2EE 应用程序通过JDBC定义为“Windows 用户”的用户帐户访问SQL Server安装,无需使用 Active Directory、运行 Web 应用程序的 Windows 机器和专有 DLL?赏金是针对该子问题的任何解决方案。整个问题显然过于广泛,无法在一篇论坛帖子中回答。

4

9 回答 9

4

我遇到了错误

登录来自不受信任的域,不能用于 Windows 身份验证

当 2012 SQL Server 数据库实例最近升级到 2016 时。为了将基于 AD 的身份验证与 JTDS 驱动程序和 SQL Server 2016 一起使用,似乎有必要同时指定useNTLMv2=truedomain=example.com后缀以建立连接。域名是绝对必要的,我通过测试确认了这一点。这是 JTDS 驱动程序版本 1.3.1。

使用基于 AD 的身份验证到带有 JTDS 1.3.1 的 SQL Server 2016 DB 的工作连接字符串示例:

jdbc:jtds:sqlserver://sqlserver2016db.example.com/MY_DB_NAME;domain=example.com;prepareSQL=2;useNTLMv2=true

更新

最近(由于大流行锁定),我发现自己还必须使用来自非域计算机的 Windows 身份验证(通过 VPN)连接到 SQL Server。这可以通过使用以下命令启动启动 SQL Server 连接的 Windows 进程来完成,例如 Eclipse / Spring Tool Suite:

C:\Windows\System32\runas.exe /netonly /user:domain\user "path_to_executable.exe"

来源:https ://www.mssqltips.com/sqlservertip/3250/connect-to-sql-servers-in-another-domain-using-windows-authentication/

在发现那个 gem 时,我还发现需要使用加密。这是我正在使用的设置(除了现在使用 /netonly 和域帐户运行可执行文件):

spring.datasource.url=jdbc:jtds:sqlserver://fqdn_of_server_including_domain/DBNAME;domain=mydomain;useNTLMv2=true;ssl=require;prepareSQL=2;
spring.datasource.username=domainaccountname_without_domain_prefix
spring.datasource.password=password
spring.datasource.testOnBorrow=true
spring.datasource.hikari.connection-test-query=SELECT 1
spring.jpa.database-platform=org.hibernate.dialect.SQLServerDialect
于 2018-09-18T18:51:54.717 回答
3

你所描述的当然似乎是可行的。我在独立服务器上运行 SQL Server 2008 R2 Express,并且能够通过 jTDS 1.3.1 从单独的 Windows 机器和 Xubuntu 14.04 机器上使用该服务器上的 Windows 用户名/密码进行连接。

在运行 SQL Server 的机器上,我创建了一个名为“kilian”的 Windows 用户。在 SQL Server 本身中,我为NT AUTHORITY\Authenticated Users. 然后在数据库(名为“myDb”)中,我为该 SQL 登录创建了一个名为“AuthenticatedUsers”的用户。为了简单起见,我授予该用户 db_owner 对数据库的权限。

数据库用户.png

'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 身份验证,但我提供的实际值没有任何区别。(我确实使用了“whatever”,它不是服务器的名称,也不是它所属的工作组的名称。)

于 2014-10-20T12:36:57.283 回答
1

我可以看到两种可能性,1.您使用的是服务器无法理解的本地系统帐户在这种情况下,请切换到域帐户。

  1. Windows 身份验证具有不同的凭据要求,您可能无法满足这些要求。在这种情况下,请尝试更改密码以符合要求。

很可能两者都在发生。

于 2014-10-25T08:25:58.543 回答
1

主要问题是具有完整 Java 解决方案(无 DLL)的 Windows 身份验证。因此,您可以使用以下库之一:

因此,一旦您的应用程序通过上述库之一进行身份验证,您的 JDBC 应该可以使用“integratedSecurity=true;”正常运行 如果需要“authenticationScheme=JavaKerberos”。

于 2014-10-22T08:14:34.820 回答
1

替代方法

另一种解决方案是利用集成安全性。这使您的应用程序能够以当前运行应用程序的用户身份连接到数据库。这是通过添加integratedSecurity=true;到连接字符串属性来启用的。如果遇到任何问题,请确保 sqljdbc_auth.dll 可以通过类路径或在您的应用程序库中访问。

安全说明

您可能已经知道了,但只需要说确保不要像之前在演示中建议的那样授予对数据库的“经过身份验证的用户”的访问权限。确定您的应用程序作为哪个用户帐户运行,并仅授予数据库服务器中该特定用户的访问权限。

来源/附加信息

于 2014-10-21T13:12:47.977 回答
1

首先,您应该像这样编写 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.

于 2014-10-24T07:05:35.780 回答
1

请参阅此其他SO 帖子,该帖子描述了如何通过 JDBC 从 Linux 机器使用 Windows 身份验证连接到 SQL Server

于 2017-06-26T21:02:10.000 回答
0

出现此错误的可能原因之一是当您将数据源配置为使用 Windows 身份验证并且 SQL Server 将扩展保护模式与 SSL 一起使用时(但我不确定是否需要 SSL)。此模式要求客户端发送附加信息 - 签名的服务主体名称 (SPN) 和通道绑定令牌 (CBT)。在此处查看有关扩展保护模式的更多信息。目前 JTDS JDBC 和 Microsoft JDBC 驱动程序都不支持这种模式。我找不到 JTDS 的官方声明,但有一张公开的适用于 Microsoft 驱动程序。要配置扩展保护模式,请转到 SQL Server 配置管理器,选择 SQL Server 网络配置上的属性 -> %your instance% 的协议,然后更改扩展保护选项。

在此处输入图像描述

于 2020-07-02T14:56:56.783 回答
0

这是我为 jTDS 驱动程序设置的 NiFi:

数据库连接 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

于 2019-05-23T10:48:48.960 回答